[Symfony][Doctrine] Fixtures からサービスコンテナを取得する
Fixtures 内で、サービスコンテナを呼び出したくなる事はしばしばあります。
例えば User エンティティクラスが Security コンポーネントの UserInterface を実装している場合、PasswordEncoder を使いたくなりますね。 しかしそのままでは AbstractFixture クラス内でサービスコンテナが取得できないので、PasswordEncoder の取りようがありません。
そんな時は、AbstractFixture に ContainerAwareInterface を実装してしまいましょう。
// src/Acme/UserBundle/DataFixtures/ORM/LoadUserClassData.php namespace Acme\UserBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Acme\UserBundle\Entity\User; // ↓追加 use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; class LoadUserClassData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface // ←追加 { // ~ /** * @var ContainerInterface */ private $container; /** * {@inheritDoc} */ public function setContainer(ContainerInterface $container = null) { $this->container = $container; } // ~ }
これで load が実行される前にサービスコンテナが格納されます。
実際に load 時に使用する場合は次の様な感じです。
public function load(ObjectManager $manager) { $factory = $this->container->get('security.encoder_factory'); $user1 = new User(); $user1->setUserName('issei'); $user1->setSalt(hash('sha512', mt_rand(111111, 999999))); $encoder = $factory->getEncoder($user1); $user1->setPassword($encoder->encodePassword('hogehoge', $user1->getSalt())); }
詳しくは公式のドキュメントを参照
http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#using-the-container-in-the-fixtures