【问题标题】:Trying to define my controllers as service in Symfony2 — the arguments are never passed to the constructor试图在 Symfony2 中将我的控制器定义为服务——参数永远不会传递给构造函数
【发布时间】:2012-09-25 21:13:21
【问题描述】:

所以,这是我刚刚构建的控制器:

namespace MDP\API\ImageBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class RetrieverController {

    private $jsonResponse;

    private $request;

    public function __construct(JsonResponse $jsonResponse, Request $request) {
        $this->jsonResponse = $jsonResponse;
        $this->request = $request;
    }

    /**
     * @Route("/image/{amount}")
     * @Template("MDPAPIImageBundle:Retriever:index.json.twig")
     */
    public function retrieve($amount)
    {
    }
}

我想让这个控制器作为服务工作,以使用 DependencyInjection。所以,这是我的services.xml 文件:

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">


    <services>
        <service id="mdpapi_image.json_response" class="Symfony\Component\HttpFoundation\JsonResponse" />
        <service id="mdpapi_image.request" class="Symfony\Component\HttpFoundation\Request" />
        <service id="mdpapi_image.controller.retriever" class="MDP\API\ImageBundle\Controller\RetrieverController">
            <argument type="service" id="mdpapi_image.json_response" />
            <argument type="service" id="mdpapi_image.request" />
        </service>
    </services>
</container>

但是,当我尝试执行我的控制器时,我总是得到这个异常:

可捕获的致命错误:传递给 MDP\API\ImageBundle\Controller\RetrieverController::__construct() 的参数 1 必须是 Symfony\Component\HttpFoundation\JsonResponse 的实例,没有给出,在 /home/steve 中调用/projects/APIs/app/cache/dev/jms_diextra/controller_injectors/MDPAPIImageBundleControllerRetrieverController.php 在第 13 行并在 /home/steve/projects/ImageAPI/ImageBundle/Controller/RetrieverController.php 第 13 行定义

当我处于开发模式时,我看到 Symfony 在缓存文件中生成了这个文件...

class RetrieverController__JMSInjector
{
    public static function inject($container) {
        $instance = new \MDP\API\ImageBundle\Controller\RetrieverController();
        return $instance;
    }
}

如何才能将参数正确添加到控制器中,就像在我的 services.xml 文件中指定的那样?

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    刚刚找到您问题的答案,希望这对您(或发现此问题的其他人)有所帮助

    <?php
    namespace MDP\API\ImageBundle\Controller;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
    
    /**
    * @Route("/image", service="mdpapi_image.controller.retriever")
    */
    class RetrieverController {
    
        private $jsonResponse;
    
        private $request;
    
        public function __construct(JsonResponse $jsonResponse, Request $request) {
            $this->jsonResponse = $jsonResponse;
            $this->request = $request;
        }
    
        /**
         * @Route("/{amount}")
         * @Template("MDPAPIImageBundle:Retriever:index.json.twig")
         */
        public function retrieve($amount)
        {
        }
    }
    

    来源:

    http://richardmiller.co.uk/2011/10/25/symfony2-routing-to-controller-as-service-with-annotations/

    http://symfony.com/doc/current/cookbook/controller/service.html

    【讨论】:

      【解决方案2】:

      所以,我解决了我的问题。我不得不停止在我的控制器中使用注释并更改了我的 routing.yml 所以直接编写路由。

      image_retrieve:
          pattern:   /image/{amount}
          defaults:  { _controller: mdp_api_image_retriever_retrieve:retrieve }
          requirements:
            _method:  GET
      

      这解决了整个问题。注释的问题在于,在第 90 行的这个类(JMS\DiExtraBundle\HttpKernel\ControllerResolver)上,在 Symfony 核心中,您会看到这个核心:

      // If the cache warmer tries to warm up a service controller that uses
      // annotations, we need to bail out as this is handled by the service
      // container directly.
      if (null !== $metadata->getOutsideClassMetadata()->id
                      && 0 !== strpos($metadata->getOutsideClassMetadata()->id, '_jms_di_extra.unnamed.service')) {
                  return;
      }
      

      然后在第 69 行,它尝试从返回的数据中调用方法 call_user_func,该数据为空。

      换句话说,使用注解和创建你的控制器即服务不能一起工作。我在调试这个问题上浪费了 4 个小时,所以我希望这对以后的人有帮助:)

      【讨论】:

      • 看我的回答,可以用注解
      【解决方案3】:

      好像你忘了写一个extension class那个loads你的services.xml文件:

      namespace MDP\API\ImageBundle\DependencyInjection;
      
      use Symfony\Component\HttpKernel\DependencyInjection\Extension;
      use Symfony\Component\DependencyInjection\ContainerBuilder;
      use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
      use Symfony\Component\Config\FileLocator;
      
      class ImageExtension extends Extension
      {
          /**
           * @param array $configs
           * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
           */
          public function load(array $configs, ContainerBuilder $container)
          {
              $loader = new XmlFileLoader(
                  $container, 
                  new FileLocator(__DIR__.'/../Resources/config')
              );
      
              $loader->load('services.xml');
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-09
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 2017-07-26
        • 2016-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多