2011-09-22 9 views
38

मैं अपने सिम्फनी 2 एप्लिकेशन में कुछ टर्मिनल कमांड चाहता हूं। मैं example in the cookbook से गुजर चुका हूं, लेकिन मुझे यह नहीं पता था कि मेरी सेटिंग्स, मेरी इकाई प्रबंधक और मेरी संस्थाओं को कैसे एक्सेस किया जाए। निर्माता में, मैं कंटेनर (जो मुझे सेटिंग्स और संस्थाओं के लिए उपयोग उपज चाहिए)सिम्फनी 2 कंसोल कमांड में मेरी संस्थाओं और इकाई प्रबंधन का उपयोग कैसे करें?

$this->container = $this->getContainer(); 

का उपयोग कर पाने लेकिन यह कॉल एक त्रुटि उत्पन्न करता है:

Fatal error: Call to a member function getKernel() on a non-object in /Users/fester/Sites/thinkblue/admintool/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php on line 38

असल में, ContainerAwareCommand- में> getContainer()

$this->getApplication() 

न्यूल देता है और अपेक्षित वस्तु नहीं है। मुझे लगता है कि मैंने कुछ महत्वपूर्ण कदम छोड़ा, लेकिन कौन सा? और अंत में मैं अपनी सेटिंग्स और संस्थाओं का उपयोग कैसे कर पाऊंगा?

+0

मैं एक ही त्रुटि हो रहा है (और मैं 'getContainer ऐक्सेस करने का प्रयास() 'MyCommand-> execute()' के अंदर 'लेकिन अभी भी वही घातक त्रुटि प्राप्त करें। मेरा' कमांडटेस्ट \ PHPUnit_Framework_Testcase' बढ़ाता है और मैं इसे 'phpunit -c app src/companyName/MyBundle/Test/Commands/MyCommandTest.php' के माध्यम से चलाता हूं। कोई विचार क्या गलत हो सकता है? –

उत्तर

71

मुझे लगता है कि आपको सीधे निर्माता में कंटेनर पुनर्प्राप्त नहीं करना चाहिए। इसके बजाय, इसे configure विधि या execute विधि में पुनर्प्राप्त करें। मेरे मामले में, मुझे इस तरह की विधि execute की शुरुआत में ही मेरी इकाई प्रबंधक मिलती है और सबकुछ ठीक काम कर रहा है (सिम्फनी 2.1 के साथ परीक्षण किया गया है)।

protected function execute(InputInterface $input, OutputInterface $output) 
{ 
    $entityManager = $this->getContainer()->get('doctrine')->getEntityManager(); 

    // Code here 
} 

मुझे लगता है कि आवेदन वस्तु की इन्स्टेन्शियशन अभी तक है जब आप अपने निर्माता जो परिणामस्वरूप यह त्रुटि उत्पन्न में getContainer बुला रहे हैं नहीं किया जाता है। त्रुटि getContainer विधि करने के लिए tyring से आता है:

$this->container = $this->getApplication()->getKernel()->getContainer(); 

getApplication के बाद से अभी तक एक वस्तु नहीं है, तो आप एक त्रुटि कह या एक गैर वस्तु पर एक विधि getKernel बुला रहे हैं मिलता है।

अद्यतन: Symfony के नए संस्करण में, getEntityManager पदावनत किया गया है (और अब तक पूरी तरह हटा दिया गया है सकते हैं)। इसके बजाय $entityManager = $this->getContainer()->get('doctrine')->getManager(); का उपयोग करें। इसे इंगित करने के लिए Chausser पर धन्यवाद।

अपडेट 2: सिम्फनी 4 में, ऑटो-वायरिंग का उपयोग आवश्यक कोड की मात्रा को कम करने के लिए किया जा सकता है।

EntityManagerInterface चर के साथ __constructor बनाएं। यह चर आपके शेष आदेशों में पहुंच योग्य होगा। यह ऑटो-वायरिंग निर्भरता इंजेक्शन योजना का पालन करता है।

class UserCommand extends ContainerAwareCommand { 
    private $em; 

    public function __construct(?string $name = null, EntityManagerInterface $em) { 
    parent::__construct($name); 

    $this->em = $em; 
    } 

    protected function configure() { 
    **name, desc, help code here** 
    } 

    protected function execute(InputInterface $input, OutputInterface $output) { 
    $this->em->getRepository('App:Table')->findAll(); 
    } 
} 

टिप्पणी और कोड नमूना प्रदान करने के लिए @ profm2 पर क्रेडिट।

+0

मैंने यह पाया कि ओ पहले से ही, लेकिन एक नौसिखिया के रूप में, मैं अपने स्वयं के प्रश्न का उत्तर नहीं दे सका। आप कंस्ट्रक्टर में कंटेनर नहीं प्राप्त कर सकते हैं, क्योंकि यह अभी तक मौजूद नहीं है। यदि आप निष्पादन विधि में कंटेनर पुनर्प्राप्त करते हैं तो यह सब खूबसूरती से काम करता है। इसके बाद, आपके पास अपनी इकाइयों तक पहुंच सामान्य तरीके से होती है: $ myEntities = $ em-> getRepository ('Acme \ DemoBundle: Myentity') -> findAll(); –

+10

नवीनतम संस्करण के साथ -> getEntityManager(); अब - getManager() के पक्ष में बहिष्कृत है; – Chausser

+1

getContainer() विधि – tuxone

4

मुझे पता है कि मैट जवाब सवाल हल, लेकिन अगर आप एक से अधिक इकाई प्रबंधक है, तो आप इस का उपयोग कर सकते हैं:

साथ मेक model.xml:

<?xml version="1.0" encoding="UTF-8" ?> 

<container xmlns="http://symfony.com/schema/dic/services" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://symfony.com/schema/dic/services   http://symfony.com/schema/dic/services/services-1.0.xsd"> 

<services> 
    <service id="EM_NAME.entity_manager" alias="doctrine.orm.entity_manager" /> 
</services> 
</container> 

फिर इस फ़ाइल को लोड आपके DI एक्सटेंशन में

$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 
$loader->load('model.xml'); 

फिर आप इसे कहीं भी उपयोग कर सकते हैं। कंसोल कमान में निष्पादित करें:

$em = $this->getContainer()->get('EM_NAME.entity_manager'); 

और करने के लिए अंत में भूल नहीं है:

services: 
    SOME_SERVICE: 
     class: %parameter.class% 
     arguments: 
      - @EM_NAME.entity_manager 
:

$em->flush(); 

अब आप services.yml में अन्य सेवा के लिए एक तर्क के रूप में उपयोग कर सकते हैं

आशा है कि यह किसी की मदद करे।

8

ContainerAwareCommand बजाय कमान

class YourCmdCommand extends ContainerAwareCommand 

से अपने आदेश वर्ग प्रदान करता है और इस तरह इकाई प्रबंधक मिलती है:

$em = $this->getContainer()->get('doctrine.orm.entity_manager'); 
संबंधित मुद्दे