2011-09-22 14 views
38

私のSymfony2アプリケーションにいくつかのターミナルコマンドが必要です。 example in the cookbookを通過しましたが、設定、エンティティマネージャ、エンティティにアクセスする方法がわかりませんでした。コンストラクタで、私はSymfony 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()で

への呼び出しはNULLを返しますが、期待どおりのオブジェクトではありません。私はいくつか重要な一歩を踏み出したと思いますが、どちらが重要ですか?そして、私は最終的に自分の設定とエンティティをどのように使用できるでしょうか?

+0

私は同じエラーときを過ごしています(と私は 'getContainerにアクセスしようとする: –

答えて

71

コンストラクタ内のコンテナを直接取得しないでください。代わりに、configureメソッドまたはexecuteメソッドで取得します。私の場合、私はこのようなexecuteメソッドの開始時にエンティティマネージャーを取得し、すべてが正常に動作しています(Symfony 2.1でテスト済み)。

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

    // Code here 
} 

私はあなたがこのエラーになり、あなたのコンストラクタでgetContainerを呼び出しているとき、アプリケーションオブジェクトのインスタンス化がまだ行われていないと思います。エラーは何をするtyring getContainer方法から来ている:

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

getApplicationはまだオブジェクトではないので、あなたはエラーが言っても非オブジェクトのメソッドgetKernel呼びかけている取得します。

アップデート:新しいバージョンのSymfonyでは、getEntityManagerは廃止されました(これまでにすべて削除された可能性があります)。代わりに$entityManager = $this->getContainer()->get('doctrine')->getManager();を使用してください。それを指してChausserありがとうございます。

アップデート2:Symfony 4では、自動配線を使用して必要なコード量を減らすことができます。

変数を持つ__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

私は、私は自分の質問に答えることができませんでした。まだ存在しないので、コンストラクタでコンテナを取得することはできません。 executeメソッドでコンテナを取得すると、すべてがうまく動作します。その後、通常の方法でエンティティにアクセスできます。 $ myEntities = $ em-> getRepository( 'Acme \ DemoBundle:Myentity') - > findAll(); –

+10

最新のバージョン - > getEntityManager(); - > getManager();を使用して非推奨になりました。 – Chausser

+1

getContainer()メソッド – tuxone

4

私はマットの答えは質問を解決し、しかし、あなたは1つのエンティティマネージャよりも多くした場合、あなたはこれを使用することができますことを知っている:

で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 
:あなたは今services.yml内の別のサービスでは、引数として使用することができます

$em->flush(); 

願っています。 )(

$em = $this->getContainer()->get('doctrine.orm.entity_manager'); 
8

はContainerAwareCommandの代わりに、コマンド

class YourCmdCommand extends ContainerAwareCommand 

からあなたのコマンドクラスを拡張し、このようなエンティティマネージャを取得します私の `CommandTest extends \ PHPUnit_Framework_Testcase`を実行し、` phpunit -c app src/CompanyName/MyBundle/Tests/Commands/MyCommandTest.php`を使って実行します。どんなアイデアが間違っている可能性がありますか?

関連する問題