当我在控制器(ClientDomainController)中调用它时,我遇到了一个恼人的问题:
$this->getDoctrine()->getManager();
我收到了这个错误:
Call to a member function has() on null
我查看了堆栈跟踪,看到了:
$this->container is null
我的控制器从Symfony Controller组件扩展:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
有趣的是,在另一个控制器(HomeController)中,我做了完全相同的事情:
这没有任何错误。
HomeController和ClientDomainController之间唯一的区别是第二个是服务。所以我在services.yml文件中写了它:
services:
client_domain:
class: AppBundle\Controller\ClientDomainController
最后,我测试了许多内容,例如为我的控制器创建一个构造函数,并将其添加到services.yml文件中(对于函数文件从未做过的事情):
arguments: [ 'doctrine.orm.entity_manager' ]
答案 0 :(得分:2)
当您将控制器注册为服务时,Symfony会像您告诉它一样创建它。
不同之处在于,尽管您的控制器实现了ContainerAwareInterface
(通过扩展Controller
类),但最终没有人调用setContainer
方法来使用此接口并设置$container
的价值。您必须在services.yml配置中手动执行此操作,如:
calls:
- [ setContainer, [ @service_container ] ]
但这不是最佳解决方案
将控制器注册为服务通常很好。它使它们更易于测试和维护。
但只要您坚持OOP的良好规则,情况就是如此。 在这种情况下,当您传递整个容器时,它意味着:
简而言之,依赖应该像最后一样通过控制器传递,或者当仅在此特定操作中使用依赖时,可以使用action-based dependency injection。
实际上,最好的解决方案甚至不是扩展基类Controller
类以使控制器框架独立。
答案 1 :(得分:0)
你的控制器应该是这样的:
class HelperController extends Controller
{
/**
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
* HelperController constructor.
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
}
和配置文件(在我的情况下是xml)
<service id="xxx.helper_controller" class="xxx\EspacePROBundle\Controller\HelperController">
<argument type="service" id="service_container" />
</service>
我希望它有所帮助。
答案 2 :(得分:-1)
如Jakub Matczak的回答所述,未设置控制器的DI容器。
或者将calls
部分添加到services.yml中,您可以在要使用控制器的类的构造函数中调用setContainer
。
use App\Controller\MyController;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MyClass {
/**
* The injected controller
* @var MyController
*/
protected $my_controller;
public function __construct(MyController $my_controller, ContainerInterface $container) {
$this->my_controller = $my_controller;
$this->my_controller->setContainer($container);
}
}