在编译器传递中使用服务时类不存在

时间:2016-08-25 15:38:01

标签: php dependency-injection symfony

我注意到一些令人讨厌的行为甚至可能是symfony中的一个错误?我不知道......以下是重新记录的步骤:

1。安装symfony

我安装了symfony 3.1.3,并安装了cli安装程序:

$ symfony new myproject

2。添加一些服务

我在app/config/services.yml中添加了服务定义:

services:
    app.helper:
        class: AppBundle\Service\AppHelper
        arguments: ["@service_container"]

我添加了相应的服务类:

<?php
namespace AppBundle\Service;

use Symfony\Component\DependencyInjection\ContainerInterface;

class AppHelper
{
    /**
     * @var ContainerInterface
     */
    private $container;

    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $em;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->em = $this->container->get('doctrine.orm.entity_manager');
    }

    /**
     * Returns stuff.
     *
     * @param $key
     * @return mixed
     */
    public function getStuff($key)
    {
        return $this->em->... // get stuff
    }
}

在构造函数中,我注入容器并从中获取doctrines实体管理器。到目前为止工作正常,例如控制器内部。

3。添加编译器传递

然后我添加了一个带有空进程方法的编译器类:

<?php
namespace AppBundle\DependencyInjection;


use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class MenuItemCompilerPass implements CompilerPassInterface
{
    /**
     * Collect modules menu items.
     *
     * @param ContainerBuilder $container
     */
    public function process(ContainerBuilder $container)
    {
    }
}

我把它添加到了bundle类中:

<?php
namespace AppBundle;

use AppBundle\DependencyInjection\MenuItemCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class AppBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new MenuItemCompilerPass());
    }
}

4。实现失败的代码

现在,我想访问AppHelper process方法中的MenuItemCompilerPass服务:

/**
 * Collect modules menu items.
 *
 * @param ContainerBuilder $container
 */
public function process(ContainerBuilder $container)
{
    $stuff = $container->get('app.helper')->getStuff('something');
}

这会导致以下错误:

ReflectionException in ContainerBuilder.php line 862: Class does not exist

事实证明,当我删除

$this->em = $this->container->get('doctrine.orm.entity_manager');
来自AppHelper中的构造函数的

它再次起作用。

有人能说出问题所在吗?

1 个答案:

答案 0 :(得分:5)

永远不会在编译器传递中从容器中获取服务。仅适用于定义。

但是,您可以从容器中获取参数。因此,不要执行$host = $container->get('app.helper')->getParameter('database_host');,而只需执行$host = $container->getParameter('database_host');

此外,永远不会在服务中注入容器。只需直接注入@doctrine.orm.entity_manager服务。