Symfony2 config.ymlから構成設定を読み取るにはどうすればよいですか?


191

私はconfig.ymlファイルに次のように設定を追加しました:

app.config:
    contact_email: somebody@gmail.com
    ...

私の人生では、それを変数に読み取る方法がわかりません。私は私のコントローラーの1つでこのようなものを試しました:

$recipient =
$this->container->getParameter('contact_email');

しかし、私は言ってエラーが出ます:

パラメータ「contact_email」を定義する必要があります。

キャッシュをクリアしました。また、Symfony2のリロードされたサイトのドキュメントをどこでも調べましたが、これを行う方法を見つけることができません。

たぶん疲れすぎてこれを理解できません。誰かがこれを手伝ってくれる?

回答:


194

むしろ定義よりcontact_emailapp.configでそれを定義し、parametersエントリー:

parameters:
    contact_email: somebody@gmail.com

これで、コントローラー内で行っている呼び出しが機能するようになります。


4
これはDev / Prod環境でどのように機能しますか?したがって、テストの場合はメールをテストメールに送信して、プロダクションで別のメールを取得する必要があります
Phill Pafford 2012年

2
@Phill:symfony2で標準のswiftmailerを使用している場合は、config_dev.ymlで次の設定を使用 swiftmailer: delivery_address: dev@example.com できます。詳細については、Symfony2クックブックをご覧ください
Pierre

4
このステートメントを使用するときにコンテナークラスをどこにでも注入する必要がありますか(コントローラー、エンティティ、クラス)$ this-> container-> getParameter( 'contact_email'); ?または、コンテナークラスを注入せずにこれを行う簡単な方法はありますか?
webblover 2014

1
このソリューションによれば、ネストされたプロパティにどのようにアクセスできますか?
Ousmane 2014

1
@webblover- %parameter_name%表記法(YAMLの場合)を使用してパラメーター自体を挿入するだけ
MauganRa

173

移動の溶液ながらcontact_emailには、parameters.yml他の回答で提案されているように、簡単ですが、あなたは多くのバンドルを扱う場合には、簡単にパラメータファイルを乱雑にするか、コンフィギュレーションのネストされたブロックを扱う場合。

  • まず、質問に厳密に答えます。
  • 後で、共通のスペースをパラメーターとして渡さずに、サービスからこれらの構成を取得する方法を説明します。

最初のアプローチ:分離された構成ブロック、パラメーターとして取得

拡張子付き(ここでは拡張機能の詳細)を使用すると、これをのさまざまなブロックに簡単に "分離"しconfig.ymlて、コントローラーから取得可能なパラメーターとして挿入できます。

内部の拡張クラスの内部 DependencyInjectionディレクトリように書き込みます。

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        // The next 2 lines are pretty common to all Extension templates.
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // This is the KEY TO YOUR ANSWER
        $container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ] );

        // Other stuff like loading services.yml
    }

次に、config.yml、config_dev.ymlに次のように設定します

my_nice_project:
    contact_email: someone@example.com

config.ymlあなたの中でそれを処理できるようにするには、MyNiceBundleExtensionあなたも必要になりますConfigurationは、同じ名前空間のクラス。

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root( 'my_nice_project' );

        $rootNode->children()->scalarNode( 'contact_email' )->end();

        return $treeBuilder;
    }
}

次に、元の質問で望んだように、コントローラーから構成を取得できますが、parameters.ymlクリーンな状態を保ち、それをconfig.yml別のセクションでます。

$recipient = $this->container->getParameter( 'my_nice_project.contact_email' );

2番目のアプローチ:分離された構成ブロック、構成をサービスに注入

同様の何かを探しているがサービスから設定を取得する読者にとっては、「パラメータ」の共通スペースを乱雑にせず、必要もない、より良い方法があります。 container、サービスに渡すます(コンテナ全体を渡すことは、避ける)。

上記のこのトリックは、まだあなたの設定のパラメータ空間に「注入」します。

それにもかかわらず、サービスの定義をロードした後、たとえばsetConfig()サービスにのみブロックを注入するようなメソッド呼び出しを追加できます。

たとえば、Extensionクラスでは次のようになります。

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // Do not add a paramater now, just continue reading the services.
        $loader = new YamlFileLoader( $container, new FileLocator( __DIR__ . '/../Resources/config' ) );
        $loader->load( 'services.yml' );

        // Once the services definition are read, get your service and add a method call to setConfig()
        $sillyServiceDefintion = $container->getDefinition( 'my.niceproject.sillymanager' );
        $sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'contact_email' ] ) );
    }
}

次に、services.yml絶対的な変更なしに、通常どおりサービスを定義します。

services:
    my.niceproject.sillymanager:
        class: My\NiceProjectBundle\Model\SillyManager
        arguments: []

次に、SillyManagerクラスにメソッドを追加します。

class SillyManager
{
    private $contact_email;

    public function setConfig( $newConfigContactEmail )
    {
        $this->contact_email = $newConfigContactEmail;
    }
}

これはスカラー値の代わりに配列でも機能することに注意してください!ウサギのキューを構成し、ホスト、ユーザー、パスワードが必要だと想像してください。

my_nice_project:
    amqp:
        host: 192.168.33.55
        user: guest
        password: guest

もちろん、ツリーを変更する必要がありますが、次のようにすることができます。

$sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'amqp' ] ) );

そしてサービスで次のようにします:

class SillyManager
{
    private $host;
    private $user;
    private $password;

    public function setConfig( $config )
    {
        $this->host = $config[ 'host' ];
        $this->user = $config[ 'user' ];
        $this->password = $config[ 'password' ];
    }
}

お役に立てれば!


最初のアプローチとドキュメントの何が違うのか疑問に思っているのであれば、設定値がMyNiceProjectExtension->load()次の行を含むメソッドのパラメーターに変換されるということです$container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ]);。シャビありがとう!
jxmallett 2015

完璧な答え、sym symonyはパラメーターと同じようにconfigにアクセスすることを許可しません。
Martin Lyne

これは良い答えですが、アプリケーションを「設定」するSymfonyの鈍い方法を明らかにします。それらにアクセスするために特定のサービスを作成して呼び出す必要がある場合に、任意の環境設定ファイルがあることの意味は何ですか。Symfonyの誰かがそこに座って、「開発者が実際にアクセスできる環境固有の値をアプリケーションに提供したいのではないか」と気づかなかったのではないでしょうか。彼らは「STKTFANREO」のデザインパターンに従っています:「ノブをFに設定し、 'emを切り落とします」
eggmatters

特に並列化された自動テストの展開にいくつかのアプリケーションがあり、特にチームが主にモデルまたはロジックであるバンドルを開発するときに、ユーザーフロントエンドであるアプリケーションなど、さまざまなアプリケーションで他のいくつかのチームによって消費されます。管理パネルのWebフロントとREST APIの2つです。それらのそれぞれは、別のアプリケーションを別の方法で構成してもかまいません。これには、いくつかの環境(実稼働、実稼働前、テスト、開発など)が掛けられます。これにより、1つの企業で12または15の構成を簡単に実現できます。
Xavi Montero 2016年

@XaviMontero 2番目のアプローチの指示に従いました。var_dumpで$ this-> contact_emailを実行するか、関数setConfig()にexit()を追加すると、終了しません。setConfigが呼び出されないようです
user742736

35

私はダグラスの答えに追加する必要があります、あなたはグローバル設定にアクセスできますが、symfonyはいくつかのパラメーターを翻訳します、例えば:

# config.yml
... 
framework:
    session:
        domain: 'localhost'
...

$this->container->parameters['session.storage.options']['domain'];

var_dumpを使用して、指定したキーまたは値を検索できます。


17

バンドルの一部の構成パラメーターを公開できるようにするには、そのための資料を参照する必要があります。とても簡単です:)

ここにリンクがあります:バンドルのセマンティック構成を公開する方法


正直なところ、この質問は2年以上前に尋ねられましたが、当時、上記の記事は存在しませんでした。
josef.van.niekerk 2013

10
私はその意見に同意します。誰かがこの記事を最近開いた場合に備えて、答えを設定しました。否定的な評価をありがとう-あなたは私の日を作りました。
Nikola Petkanski 2013

申し訳ありませんが、今考えてみると、私の反対票は要求されませんでした。私はあなたの貢献に感謝します、私は賛成票を投じようとしましたが、SOはもうそれを許可しません。リンクは非常に役に立ち、他の人もそれから利益を得ると確信しています!多分管理者は私の反対票を変更するのを助けることができますか?
josef.van.niekerk 2013

もう一度クリックすると元に戻せると思います。
Nikola Petkanski 2013

投票が完了してからX(5?)分以上、またはメッセージが編集されるまで、投票を取り消すことはできません
cheesemacfly


3

http://tutorial.symblog.co.uk/のコード例から簡単な方法を学びました

1)ZendeskBlueFormBundleとファイルの場所に注意してください

# myproject/app/config/config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: @ZendeskBlueFormBundle/Resources/config/config.yml }

framework:

2)Zendesk_BlueForm.emails.contact_emailとファイルの場所に注意してください

# myproject/src/Zendesk/BlueFormBundle/Resources/config/config.yml

parameters:
    # Zendesk contact email address
    Zendesk_BlueForm.emails.contact_email: dunnleaddress@gmail.com

3)$ clientで取得する方法とコントローラーのファイルの場所に注意してください

# myproject/src/Zendesk/BlueFormBundle/Controller/PageController.php

    public function blueFormAction($name, $arg1, $arg2, $arg3, Request $request)
    {
    $client = new ZendeskAPI($this->container->getParameter("Zendesk_BlueForm.emails.contact_email"));
    ...
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.