传递给控制器​​的参数必须是 ContainerInterface 的实例,给定 appDevDebugProjectContainer 的实例

Posted

技术标签:

【中文标题】传递给控制器​​的参数必须是 ContainerInterface 的实例,给定 appDevDebugProjectContainer 的实例【英文标题】:Argument passed to controller must be an instance of ContainerInterface, instance of appDevDebugProjectContainer given 【发布时间】:2015-03-12 21:06:28 【问题描述】:

为什么会出现这个错误?

可捕获的致命错误:传递给 Application\Sonata\ProductBundle\Controller\ProductAdminController::__construct() 的参数 1 必须是 ContainerInterface 的实例,给定 appDevDebugProjectContainer 的实例

这是我的 services.yml:

services:
    product_admin_controller:
      class: Application\Sonata\ProductBundle\Controller\ProductAdminController
      arguments: ["@service_container"]
      tags:
            -  name: doctrine.event_listener, event: postLoad, connection: default  

还有我的控制器:

class ProductAdminController extends Controller

    protected $container;

    public function __construct(\ContainerInterface $container)
    
        $this->container = $container;
    

【问题讨论】:

这似乎是Symfony 的经典控制器和控制器即服务概念的混合体。为什么你们既要扩展 Controller 又要通过 __construct 传递 Container 这是一个命名空间问题。使用 Symfony\Component\DependencyInjection\ContainerInterface; __construct(ContainerInterface。你真的应该使用 ContainerAware 接口。更好的是,注入你的特定依赖项而不是完整的容器。 感谢大家的帮助。主要目标是覆盖 orm 产品类并使用 mongodb odm 驱动的变体对象对其进行扩展。我尝试从第 32 页复制到以下内容 (fr.slideshare.net/jwage/…)。所以第一次尝试是注入 EntityManager (***.com/questions/20587354/…) 但我无法做到没有错误所以我尝试了 (***.com/questions/22128402/…) 【参考方案1】:

您必须通过“调用”选项注入容器,而不是我认为的参数:

services:
    product_admin_controller:
      class: Application\Sonata\ProductBundle\Controller\ProductAdminController
      arguments: ["@another_service_you_need"]
      tags:
            -  name: doctrine.event_listener, event: postLoad, connection: default  
      calls:
            -   [ setContainer,["@service_container"] ]

另外,不要忘记在你的监听器类中创建公共方法“setContainer()”。

【讨论】:

【参考方案2】:

首先,您为什么要尝试使用 __constract()?相反,您必须使用将 ContainerInterface $container 作为参数的 setContainer() 方法,它应该如下所示:

<?php
...
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;

...
class YourClass extends Controller


    public function setContainer(ContainerInterface $container = null)
    
        // your stuff
    

第二个问题:你需要将容器注入控制器做什么?您可以使用 $this->get('service_id') 语句调用任何服务,而不是直接调用容器。

【讨论】:

我使用 __construct() 函数,因为我想要制作的 mongoDB «extension» 是一种一般行为。我希望 mongoDB 变体对象始终扩展 mysql 产品对象。到目前为止,我设法通过服务将 EntityManager(按事先计划)传递给函数,但是,因为该类被调用了两次,第一次,我的 EntityManager $em 是一个对象,第二次是 null...我不明白为什么? 因为这是最好的方法吗? 对不起,但我认为“因为 mongoDB «扩展»”并没有解释什么。我仍然认为您必须将服务容器或实体管理器注入控制器。

以上是关于传递给控制器​​的参数必须是 ContainerInterface 的实例,给定 appDevDebugProjectContainer 的实例的主要内容,如果未能解决你的问题,请参考以下文章

路由怎么传递参数给控制器

Doctrine - 传递给 __construct 的参数必须是一个数组

传递给验证器()的 Laravel 参数 1 必须是 Illuminate\Http\Request 的实例,给定数组

传递给 App\Events\NoticeAnnouncement::__construct() 的参数 3 必须是 App\User 的实例

传递给 Y 的参数 X 必须是布尔值的实例,给定的布尔值 - PHP7

传递给 Illuminate\Routing\Middleware\ThrottleRequests::addHeaders() 的参数 1 必须是 please sir 的实例