首页 文章

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

提问于
浏览
3

我注意到一些令人讨厌的行为甚至可能是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.实施失败的代码

现在我想在 MenuItemCompilerPassprocess 方法中访问 AppHelper 服务:

/**
 * 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 回答

  • 5

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

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

    此外,永远不要将容器注入服务中 . 只需直接注入 @doctrine.orm.entity_manager 服务即可 .

相关问题