doulian8485
2018-02-01 23:43 阅读 122
已采纳

Symfony 3.3 - Services.yml参数(ResponseFactory) - 参数以字符串而不是对象的形式传递

The Error

Hello, I am getting the following error:

Type error: Argument 2 passed to ApiExceptionBundle\EventListener\ApiExceptionSubscriber::__construct() must implement interface ApiExceptionBundle\Component\Factory\ResponseFactoryInterface, string given, called in C:\htdocs\projects\myproject\var\cache\dev\appDevDebugProjectContainer.php on line 4293

The Call Stack Showing The Incorrect Parameter Type Being Passed

As can be seen below from the call stack, the second parameter is a string. (But it should actually be an object instantiated of that type).

at ApiExceptionSubscriber->__construct(true, 'ApiExceptionBundle\\Component\\Factory\\ResponseFactoryInterface', true, array('/admin/'))
in appDevDebugProjectContainer.php (line 4293)

The Constructor Definition

The subscriber is located at myproject\src\ApiExceptionBundle\EventListener\ApiExceptionSubscriber.php and its constructor definition is the following:

public function __construct($debug, ResponseFactoryInterface $responseFactory, $enabled = true, $excludedPaths = [])

(Notice above that it is expecting a ResponseFactoryInterface object rather than a string).

The Services.yml Entry

In myproject/src/ApiExceptionBundle/Resources/config/services.yml, the relevant entry is below:

ApiExceptionBundle\EventListener\ApiExceptionSubscriber:
        arguments:
            $responseFactory: 'ApiExceptionBundle\Component\Factory\ResponseFactoryInterface'

Other Things I've Tried

From the original example I am using, I see that there is actually an @ symbol at the beginning of the $responseFactory argument assignment in the services.yml file.

The original code that I am using as an example, has a services.yml entry similar to this:

$responseFactory: '@ApiExceptionBundle\Component\Factory\ResponseFactoryInterface'

Unfortunately when I try to add the @ symbol in my code (like above), it gives me this error:

PHP Fatal error:  Uncaught Symfony\Component\DependencyInjection\Exception\RuntimeException: Cannot dump de
finition because of invalid class name ('@ApiExceptionBundle\\Component\\Factory\\ResponseFactory') in C:\h
tdocs\projects\myproject\vendor\symfony\symfony\src\Symfony\Component\DependencyInjection\Dumper\PhpDumper.ph
p:1568

Questions

So, I have 2 questions:

  1. What am I doing wrong? (I'm assuming it's the way I'm referencing things in services.yml).
  2. What does the @ symbol do? Taking a guess, I think it tells the code to instantiate an object of the class referenced rather than just literally using the string. Is that correct?
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    dpwh11290 dpwh11290 2018-02-01 23:54

    For Symfony 3.3+

    Looks like you're trying to pass interfaces. Specific instance should be used instead.

    Have you tried autowiring with alias?

    # services.yml
    
    services:
        ApiExceptionBundle\YourResponseFactory: ~
        ApiExceptionBundle\Component\Factory\ResponseFactoryInterface:
            alias: ApiExceptionBundle\YourResponseFactory
    
        ApiExceptionBundle\EventListener\ApiExceptionSubscriber:
            autowire: true
    

    With PSR-4 autodiscovery

    Or you can use PSR-4 autodiscovery:

    # services.yml
    
    services:
        _defaults:
            autowire: true
    
        ApiExceptionBundle\: ~
            resource: ../ # path to ApiExceptionBundle directory
    
        ApiExceptionBundle\Component\Factory\ResponseFactoryInterface:
            alias: ApiExceptionBundle\YourResponseFactory
    

    Symfony 3.4+

    Since Symfony 3.4 you can ommit the alias thanks to autoaliasing for single-services from your code.

    # services.yml
    
    services:
        _defaults:
            autowire: true
    
        ApiExceptionBundle\: ~
            resource: ../ # path to ApiExceptionBundle directory
    
    点赞 评论 复制链接分享

相关推荐