मैं सिम्फनी 2 config.yml से कॉन्फ़िगरेशन सेटिंग्स कैसे पढ़ूं?


191

मैंने अपनी config.yml फ़ाइल में इस तरह एक सेटिंग जोड़ी है:

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

मेरे जीवन के लिए, मैं यह नहीं जान सकता कि इसे एक चर में कैसे पढ़ा जाए। मैंने अपने कुछ नियंत्रकों में इस तरह की कोशिश की:

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

लेकिन मुझे यह कहते हुए एक त्रुटि हुई:

पैरामीटर "contact_email" को परिभाषित किया जाना चाहिए।

मैंने अपना कैश साफ़ कर दिया है, मैंने सिम्फ़नी 2 के पुनः लोड किए गए साइट डॉक्यूमेंटेशन को भी हर जगह देखा, लेकिन मुझे यह पता नहीं चल पाया कि यह कैसे करना है।

शायद अभी यह पता लगाने के लिए बहुत थक गया। क्या कोई इसके लिए सहायता कर सकता है?

जवाबों:


194

contact_emailभीतर परिभाषित करने के बजाय app.config, इसे एक parametersप्रविष्टि में परिभाषित करें :

parameters:
    contact_email: somebody@gmail.com

आपको अपने नियंत्रक के भीतर की गई कॉल को ढूंढना चाहिए जो अब काम करता है।


4
यह देव / उत्पाद वातावरण के साथ कैसे काम करेगा? इसलिए परीक्षण के लिए मैं चाहता हूं कि ईमेल एक परीक्षण ईमेल पर भेजें और उत्पादन को एक और ईमेल मिल जाएगा
फिल पाफर्ड

2
@Phill: यदि आप अपने symfony2 में मानक स्विफ्टमेलर का उपयोग कर रहे हैं, तो आप अपने config_dev.yml में निम्न सेटिंग का उपयोग कर सकते हैं: swiftmailer: delivery_address: dev@example.com आप Symfony2 रसोई की किताब
पियरे

4
क्या मुझे कंटेनर क्लास को हर जगह इंजेक्ट करना चाहिए (कंट्रोलर, एंटिटी, क्लास) जब मैं इस स्टेटमेंट का उपयोग करता हूं $-> कंटेनर-> getParameter ('contact_email'); ? या कंटेनर कक्षा को इंजेक्ट किए बिना ऐसा करने का एक सरल तरीका है?
वेबब्लोवर

1
इस समाधान के अनुसार मैं नेस्टेड संपत्तियों तक कैसे पहुंच सकता हूं?
Ousmane

1
@webblover सिर्फ पैरामीटर का उपयोग कर %parameter_name%- अंकन (
YAML में

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

दूसरा चरण: अलग-अलग कॉन्फिग ब्लॉक, एक सर्विस में कॉन्फिग को इंजेक्ट करता है

कुछ इसी तरह की तलाश करने वाले पाठकों के लिए, लेकिन किसी सेवा से कॉन्फिगर करने के लिए, यहां तक ​​कि एक अच्छा तरीका भी है जो कभी भी "पैरामैटर्स" के कॉमन स्पेस को जकड़ता नहीं है और इसकी आवश्यकता भी नहीं होती है container सर्विस पास करने की (पूरे कंटेनर को पास करने का अभ्यास होता है) बचने के लिए)।

ऊपर दिया गया यह ट्रिक अभी भी आपके कॉन्फिगरेशन स्पेस को "इंजेक्ट" करता है।

फिर भी, आपकी सेवा की परिभाषा को लोड करने के बाद, आप उदाहरण के लिए एक विधि-कॉल जोड़ सकते हैं setConfig() जो उस ब्लॉक को केवल सेवा में इंजेक्ट करता है।

उदाहरण के लिए, एक्सटेंशन क्लास में:

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' ]);:। धन्यवाद Xavi!
jxmallett

बिल्कुल सही जवाब, शर्मनाक सहानुभूति आपको उसी तरह से कॉन्फ़िगर करने की अनुमति नहीं देती है जैसे यह पैरामीटर करता है।
मार्टिन लिन

यह एक अच्छा जवाब है, लेकिन यह एक आवेदन को "कॉन्फ़िगर" करने के सिम्फनी के अप्रिय तरीके को उजागर करता है। जब आपको लिखने और विशिष्ट सेवाओं को एक्सेस करने के लिए इनवॉइस करने के लिए मनमाना पर्यावरण कॉन्फिग फाइल होने की बात है। क्या सिम्फनी के किसी व्यक्ति ने वहां बैठकर महसूस नहीं किया, 'हो सकता है कि डेवलपर्स वास्तव में अपने अनुप्रयोगों में पर्यावरण के विशिष्ट मूल्य प्रदान करना चाहते हों, जिससे वे एक्सेस कर सकें' कॉन्फिग फाइल की बात है? वे "STKTFANREO" डिज़ाइन पैटर्न का अनुसरण कर रहे हैं: "knobs को F'd पर सेट करें और उन्हें" चीर दें "
eggmatters

इसके कई अनुप्रयोग हैं, विशेष रूप से समानांतर स्वचालित परीक्षण की तैनाती में, और विशेष रूप से जब एक टीम एक बंडल विकसित करती है जो मुख्य रूप से मॉडल या तर्क है जो विभिन्न अनुप्रयोगों में कई अन्य टीमों द्वारा खपत होती है, उदाहरण के लिए एक अनुप्रयोग जो एक उपयोगकर्ता फ्रंट-एंड है, एक और जो एक व्यवस्थापक-पैनल वेब फ्रंट है और दूसरा वह जो एक REST API है। उनमें से प्रत्येक अलग से कॉन्फ़िगर करने के लिए तैयार एक अलग अनुप्रयोग है। यह कई वातावरण (उत्पादन, पूर्व-उत्पादन, परीक्षण, डेवेल, आदि) से गुणा किया जाता है। यह एक ही कंपनी में 12 या 15 कॉन्फ़िगरेशन में आसानी से पैदावार देता है।
ज़ावि मोंटेरो

@XaviMontero मैंने आपके निर्देश का पालन किया है सेकंड: और जब var_dump $ यह-> contact_email या फंक्शन setConfig में () जोड़ें तो यह बाहर नहीं निकलता है। ऐसा लग रहा है कि सेटऑनफिग को बुलाया नहीं जाता है
user742736

35

मुझे डगलस के उत्तर में जोड़ना होगा, आप वैश्विक कॉन्फिग को एक्सेस कर सकते हैं, लेकिन सिम्फनी कुछ मापदंडों का अनुवाद करती है, उदाहरण के लिए:

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

कर रहे हैं

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

आप एक निर्दिष्ट कुंजी या मान खोजने के लिए var_dump का उपयोग कर सकते हैं।


17

अपने बंडल के लिए कुछ कॉन्फ़िगरेशन मापदंडों को उजागर करने में सक्षम होने के लिए आपको ऐसा करने के लिए प्रलेखन से परामर्श करना चाहिए। यह करना काफी आसान है :)

यहाँ लिंक है: एक बंडल के लिए सिमेंटिक कॉन्फ़िगरेशन को कैसे उजागर किया जाए


ईमानदारी से, यह सवाल 2 साल पहले पूछा गया था, फिर, उपरोक्त लेख मौजूद नहीं था।
josef.van.niekerk

10
मैं उस कथन से सहमत हूं। मैंने उत्तर दिया है कि यदि कोई व्यक्ति आजकल इस लेख को खोलता है। नकारात्मक रेटिंग के लिए धन्यवाद - आपने मेरा दिन बना दिया।
निकोला पेटकंस्की

मेरी क्षमायाचना, अब जब कि मैं इसके बारे में सोचता हूं, तो मेरे पतन के लिए अचूक था। मैं आपके योगदान की सराहना करता हूं, मैंने इसे उभारने की कोशिश की, लेकिन एसओ इसे अनुमति नहीं देता है। लिंक सबसे उपयोगी है, और मुझे यकीन है कि अन्य लोग इससे लाभान्वित होंगे! शायद व्यवस्थापक मेरे डाउनवोट को बदलने में मदद कर सकता है ???
josef.van.niekerk

मेरा मानना ​​है कि आप पूर्ववत करने के लिए फिर से क्लिक कर सकते हैं।
निकोला पेटकंस्की

आप अपने वोट को एक्स (5?) मिनटों से अधिक समय तक नहीं कर सकते हैं, जब तक आप इसे पूरा नहीं करते हैं या जब तक संदेश संपादित नहीं किया जाता है
cheesemacfly

7

जैसे यह पहले कह रहा था - आप इंजेक्शन कंटेनर का उपयोग करके किसी भी पैरामीटर का उपयोग कर सकते हैं और इसकी पैरामीटर संपत्ति का उपयोग कर सकते हैं।

"सिम्फनी - कंटेनर सर्विस डेफिनिशन के साथ काम करना" इसके बारे में एक अच्छा लेख है।


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) ध्यान दें कि मैं इसे $ क्लाइंट में कैसे प्राप्त करूं और नियंत्रक का फ़ाइल स्थान

# 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"));
    ...
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.