Symfony2 config.yml'den yapılandırma ayarlarını nasıl okuyabilirim?


191

Ben config.yml dosyasına böyle bir ayar ekledim:

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

Hayatım boyunca, onu bir değişkene nasıl okuyacağımı anlayamıyorum. Denetleyicilerimden birinde böyle bir şey denedim:

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

Ama bir hata mesajı alıyorum:

"Contact_email" parametresi tanımlanmalıdır.

Önbelleğimi temizledim, ayrıca Symfony2 yeniden yüklenen site belgelerinin her yerine baktım, ancak bunu nasıl yapacağımı bulamıyorum.

Muhtemelen bunu anlamak için çok yorgun. Herkes bu konuda yardımcı olabilir mi?

Yanıtlar:


194

Aksine tanımlamak yerine contact_emailiçinde app.config, a tanımlamak parametersgiriş:

parameters:
    contact_email: somebody@gmail.com

Kumandanızda yaptığınız aramanın şimdi çalıştığını görmelisiniz.


4
Bu, Dev / Prod ortamlarıyla nasıl çalışır? Bu yüzden test için e-postaların bir test e-postasına gönderilmesini istiyorum ve üretim başka bir e-posta alacaktı
Phill Pafford

2
@Phill: Symfony2'nizde standart swiftmailer kullanıyorsanız, config_dev.yml dosyasında aşağıdaki ayarı kullanabilirsiniz: Symfony2 yemek kitabında swiftmailer: delivery_address: dev@example.com daha fazla bilgi bulabilirsiniz
Pierre

4
Bu ifadeyi kullandığımda konteyner sınıfını her yere (denetleyici, varlık, sınıf) enjekte etmeliyim $ this-> container-> getParameter ('contact_email'); ? veya konteyner sınıfını enjekte etmeden bunu yapmanın daha basit bir yolu var mı?
webblover

1
Bu çözüme göre iç içe geçmiş özelliklere nasıl erişebilirim?
Ousmane

1
@webblover Sadece %parameter_name%- notation (YAML içinde)
MauganRa

173

Hareketli çözümü iken contact_emailüzere parameters.ymldiğer yanıtlar teklif edildiği üzere, kolay, birçok demetleri ile uğraşmak eğer kolayca parametre dosyalarını karmakarışık edebilir veya konfigürasyonun iç içe bloklar ile uğraşmak durumunda.

  • İlk olarak, soruyu kesinlikle cevaplayacağım.
  • Daha sonra, bu yapılandırmaları hiç bir ortak alandan parametre olarak geçmeden hizmetlerden almak için bir yaklaşım vereceğim.

İLK YAKLAŞIM: Ayrılmış yapılandırma bloğu, parametre olarak alınıyor

Bir uzantı ile ( buradaki uzantılar hakkında daha fazla bilgi ), bunu kolayca farklı bloklarda "ayrılabilir" config.ymlve daha sonra denetleyiciden alınabilen bir parametre olarak enjekte edebilirsiniz.

Extension sınıfınızın içindeki DependencyInjectiondizinin içine şunu yazın:

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
    }

Sonra config.yml, config_dev.yml ve böylece ayarlayabilirsiniz

my_nice_project:
    contact_email: someone@example.com

Bunu config.ymliçinde işlemek için aynı ad alanında MyNiceBundleExtensionbir Configurationsınıfa da ihtiyacınız olacak :

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

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

        return $treeBuilder;
    }
}

Daha sonra yapılandırmayı orijinal sorunuzda istediğiniz gibi kontrol cihazınızdan alabilirsiniz, ancak parameters.ymltemizliği koruyun ve config.ymlayrı bölümlerde ayarlayın:

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

İKİNCİ YAKLAŞIM: Ayrılmış yapılandırma bloğu, yapılandırmayı bir hizmete enjekte eder

Benzer bir şey arayan ancak yapılandırmayı bir hizmetten almak için okuyucular için, "paramaters" ortak alanını asla kesmeyen ve hatta containerhizmete geçirilmesine gerek olmayan daha güzel bir yol bile vardır (tüm kapsayıcıyı geçmek pratiktir önlemek).

Yukarıdaki bu hile hala yapılandırmanızın parametre alanına "enjekte eder".

Bununla birlikte, hizmet tanımınızı yükledikten sonra, örneğin setConfig()yalnızca hizmeti engelleyen gibi bir yöntem çağrısı ekleyebilirsiniz .

Örneğin, Extension sınıfında:

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' ] ) );
    }
}

Ardından, services.ymlmutlak bir değişiklik yapmadan hizmetinizi her zamanki gibi tanımlarsınız:

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

Ve sonra SillyManagersınıfınıza, yöntemi ekleyin:

class SillyManager
{
    private $contact_email;

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

Bunun skaler değerler yerine diziler için de işe yaradığını unutmayın! Bir tavşan kuyruğu yapılandırdığınızı ve ana bilgisayar, kullanıcı ve şifre gerektiğini düşünün:

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

Tabii ki Ağacınızı değiştirmeniz gerekiyor, ancak sonra şunları yapabilirsiniz:

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

ve sonra hizmette şunları yapın:

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

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

Bu yardımcı olur umarım!


İlk yaklaşım ve dokümantasyon arasındaki neyin farklı olduğunu merak ediyorsanız, bu yapılandırma değerleri parametre dönüştürülür işte MyNiceProjectExtension->load()bu hat ile yöntemle: $container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ]);. Teşekkürler Xavi!
jxmallett

Mükemmel cevap, utanç symfony, yapılandırmaya parametrelerle aynı şekilde erişmenize izin vermez.
Martin Lyne

Bu iyi bir yanıttır, ancak Symfony'nin bir uygulamayı "yapılandırma" konusundaki geniş yolunu ortaya çıkarır. Bunlara erişmek için belirli hizmetleri yazmanız ve çağırmanız gerektiğinde rasgele ortam yapılandırma dosyalarına sahip olmanın anlamı nedir. Symfony'dan biri orada oturup fark etmemişti, 'Belki geliştiriciler aslında uygulamalarında ortama özgü değerler sağlamak isterler' Yapılandırma dosyalarının bir nevi değil mi? "STKTFANREO" tasarım modelini takip ediyorlar: "Düğmeleri F'd olarak ayarlayın ve
sökün

Özellikle paralel otomatik sınama uygulamalarında ve özellikle bir ekip, farklı uygulamalardaki diğer birkaç takım tarafından tüketilen model veya mantık olan bir paket geliştirdiğinde, örneğin kullanıcı ön ucu olan bir uygulama olduğunda, diğeri de yönetici paneli web ön yüzü ve diğeri de REST API'sidir. Bunların her biri farklı bir şekilde yapılandırmaya istekli farklı bir uygulamadır. Bu birkaç ortamla çarpılır (üretim, üretim öncesi, test, geliştirme, vb.). Bu, tek bir şirkette 12 veya 15 konfigürasyonda kolayca sonuç verir.
Xavi Montero

@XaviMontero İKİNCİ YAKLAŞIM talimatınızı izledim: ve var_dump $ this-> contact_email veya setConfig () fonksiyonuna bir exit () eklediğinde çıkmaz. Görünüşe göre setConfig çağrılmıyor
user742736

35

Douglas cevabına eklemek zorundayım, global konfigürasyona erişebilirsiniz, ancak symfony bazı parametreleri çevirir, örneğin:

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

Hangi

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

Belirtilen bir anahtar veya değeri aramak için var_dump komutunu kullanabilirsiniz.


17

Paketiniz için bazı yapılandırma parametrelerini gösterebilmek için, bunun için belgelere başvurmalısınız. Yapması oldukça kolay :)

Bağlantı şu şekildedir: Paket için Anlamsal Yapılandırma nasıl gösterilir


Dürüst olmak gerekirse, bu soru 2 yıl önce soruldu, o zamanlar yukarıdaki makale yoktu.
josef.van.niekerk

10
Bu ifadeye katılıyorum. Bugünlerde birisinin bu makaleyi açması durumunda cevabı ayarladım. Olumsuz derecelendirme için teşekkürler - benim günümü yaptın.
Nikola Petkanski

Özür dilerim, şimdi düşündüğüm için, benim aşağı oyum çağrılmadı. Katkınız için teşekkür ederim, oy vermeye çalıştım ama SO artık izin vermiyor. Bağlantı en yararlı ve eminim diğer millet ondan yararlanacak! Belki admin benim downvote değiştirmek yardımcı olabilir ???
josef.van.niekerk

Geri almak için tekrar tıklayabileceğinize inanıyorum.
Nikola Petkanski



3

Ben kod örnekten kolay yoldan öğrendim http://tutorial.symblog.co.uk/

1) ZendeskBlueFormBundle'a ve dosya konumuna dikkat edin

# 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 ve dosya konumuna dikkat edin

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

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

3) $ istemci ve denetleyicinin dosya konumuna nasıl aldığımı fark et

# 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"));
    ...
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.