【问题标题】:Container not being set when trying to use ContainerAwareInterface尝试使用 ContainerAwareInterface 时未设置容器
【发布时间】:2016-06-09 05:20:35
【问题描述】:

在 Symfony 2.8 中,此代码 $this->container 为空。

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

class EntrarYPreregistroFormSubscriber implements EventSubscriberInterface, ContainerAwareInterface
{
    use ContainerAwareTrait;

    public function preSetData(FormEvent $event)
    {
        $l = $this->container->get('logger');
        $l->notice('GOT LOGGER');
    }

    ....
}

而我的EntrarYPreregistroFormSubscriber服务配置为:

pmktconcursos.entrarypreregistro.form.subscriber:
    class: PMKT\ConcursosBundle\EventListener\EntrarYPreregistroFormSubscriber
    calls:
        - [ setContainer,[ "@service_container" ] ]

我在$l = $this->container->get('logger'); 遇到异常

request.CRITICAL: Uncaught PHP Exception Symfony\Component\Debug\Exception\FatalErrorException: "Error: Call to a member function get() on a non-object" at /Users/vmarquez/Proyectos/GrupoPMKT/Promoticket/current/dev/chedraui1607/chedraui1607/src/PMKT/ConcursosBundle/Form/EventListener/EntrarYPreregistroFormSubscriber.php line 30 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 0): Error: Call to a member function get() on a non-object at /Users/vmarquez/Proyectos/GrupoPMKT/Promoticket/current/dev/chedraui1607/chedraui1607/src/PMKT/ConcursosBundle/Form/EventListener/EntrarYPreregistroFormSubscriber.php:30)"}

我错过了什么吗?

【问题讨论】:

  • 您为什么不使用通常的方式将参数传递给服务?只需将容器定义为参数,并将其传递给构造函数?
  • 这就是我使用 Denis 的解决方案。即便如此,我还是很好奇我在使用 Trait 时做错了什么。

标签: php symfony containers traits


【解决方案1】:

您正在制作表单事件侦听器,因此在您的表单类型中您有类似$builder->addEventSubscriber(new EntrarYPreregistroFormSubscriber()); 的内容,因此您可以看到表单事件侦听器的工作方式与常规事件侦听器略有不同。因为是你创建了对象,所以你应该调用setContainer($serviceContainer)。为此,您应该在表单类型中包含服务容器。为此,您应该在控制器中创建表单时将其作为选项传递

// in controller
$object = ...;
$form = $this->createForm(new YourFormType(), $object, array('service_container' => $this->get('service_container')));

// in YourFormType
$listener = new EntrarYPreregistroFormSubscriber();
$listener->setContainer($options['service_container']);
$builder->addEventSubscriber($listener);
...
// in setDefaultOptions method
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        ...
        'service_container' => null,
    ));
}

【讨论】:

  • 嗯,丹尼斯,这是我正在考虑的一种解决方案(另一种是具体的服务配置以及我需要的服务,正如您在评论中所建议的那样)。谢谢你的推荐。我将根据您在此答案上的推理进行深入思考,看看我是否可以提供更干净的解决方案。
  • 无论如何,如果您的第二个解决方案是从服务配置中删除调用并将其转换为参数,那么您需要在表单类型中使用 new EntrarYPreregistroFormSubscriber($serviceContainer)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
相关资源
最近更新 更多