Symfony2アプリケーションにいくつかのターミナルコマンドを追加します。 クックブックの例 を試しましたが、ここで自分の設定、エンティティマネージャ、およびエンティティにアクセスする方法を見つけることができませんでした。コンストラクターで、コンテナーを取得します(これにより、設定とエンティティーにアクセスできるようになります)。
$this->container = $this->getContainer();
しかし、この呼び出しはエラーを生成します:
致命的なエラー:38行目の/Users/fester/Sites/thinkblue/admintool/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.phpの非オブジェクトでメンバー関数getKernel()を呼び出す
基本的に、ContainerAwareCommand-> getContainer()での呼び出し
$this->getApplication()
期待どおりのオブジェクトではなくNULLを返します。重要な一歩を省いたと思いますが、どれですか?そして、最終的に設定とエンティティをどのように使用できるようになりますか?
コンストラクタでコンテナを直接取得しないでください。代わりに、configure
メソッドまたはexecute
メソッドで取得してください。私の場合、このようなexecute
メソッドの開始時にエンティティマネージャーを取得し、すべてが正常に動作しています(Symfony 2.1でテスト済み)。
_protected function execute(InputInterface $input, OutputInterface $output)
{
$entityManager = $this->getContainer()->get('doctrine')->getEntityManager();
// Code here
}
_
このエラーが発生するコンストラクタでgetContainer
を呼び出しているとき、アプリケーションオブジェクトのインスタンス化はまだ行われていないと思います。エラーはgetContainer
メソッドの実行が原因です。
_$this->container = $this->getApplication()->getKernel()->getContainer();
_
getApplication
はまだオブジェクトではないため、非オブジェクトに対してgetKernel
メソッドを呼び出すか呼び出しているというエラーが表示されます。
Update:Symfonyの新しいバージョンでは、getEntityManager
は非推奨になりました(そして今では完全に削除できました)。代わりに$entityManager = $this->getContainer()->get('doctrine')->getManager();
を使用してください。 Chausser に感謝します。
Update 2:Symfony 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の功績。
commandではなくContainerAwareCommandからコマンドクラスを拡張します
class YourCmdCommand extends ContainerAwareCommand
そして、このようなエンティティマネージャを取得します:
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
マットの答えが問題を解決したことは知っていますが、エンティティマネージャーが複数いる場合は、これを使用できます。
次を使用して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');
最後に忘れないでください:
$em->flush();
これをservices.ymlの別のサービスの引数として使用できます:
services:
SOME_SERVICE:
class: %parameter.class%
arguments:
- @EM_NAME.entity_manager
これが誰かを助けることを願っています。