试图在Symfony2中将我的控制器定义为服务 - 参数永远不会传递给构造函数

时间:2012-09-25 21:13:22

标签: php symfony

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

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中调用第13行的/projects/APIs/app/cache/dev/jms_diextra/controller_injectors/MDPAPIImageBundleControllerRetrieverController.php,在/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文件中指定的那样?

3 个答案:

答案 0 :(得分:3)

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

<?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

答案 1 :(得分:1)

所以,我解决了我的问题。我不得不在我的控制器中停止使用Annotations并更改了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,该数据为null。

换句话说,使用Annotation并将控制器创建为服务不能一起工作。我失去了4个小时调试这个问题,所以我希望这可能会帮助将来的某个人:)

答案 2 :(得分:0)

好像你忘记写extension class services.xmlnamespace 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'); } } 文件:

{{1}}