Symfony 3.3 - Services.yml 参数 (ResponseFactory) - 参数作为字符串而不是对象传入

Symfony 3.3 - Services.yml Argument (ResponseFactory) - Parameter Being Passed In As String Instead of Object

错误

您好,我收到以下错误:

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

显示传递的参数类型不正确的调用堆栈

从下面的调用栈可以看出,第二个参数是一个字符串。 (但它实际上应该是该类型实例化的对象)。

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

构造函数定义

订户位于myproject\src\ApiExceptionBundle\EventListener\ApiExceptionSubscriber.php,其构造函数定义如下:

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

(注意上面它期待一个 ResponseFactoryInterface 对象而不是一个字符串)。

Services.yml条目

myproject/src/ApiExceptionBundle/Resources/config/services.yml中,相关条目如下:

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

我尝试过的其他东西

从我使用的原始示例中,我看到在 $responseFactory 参数的开头实际上有一个 @ 符号 services.yml 文件中的赋值。

我用作示例的原始代码有一个类似于此的 services.yml 条目:

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

不幸的是,当我尝试在我的代码中添加 @ 符号 时(如上),它给我这个错误:

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

问题

那么,我有两个问题:

  1. 我做错了什么? (我假设这是我在 services.yml 中引用事物的方式)。
  2. @ 符号有什么作用?猜测一下,我认为它告诉代码实例化引用的 class 的对象,而不是仅仅使用字符串。对吗?

对于 Symfony 3.3+

您似乎在尝试传递接口。应使用特定实例代替。

你试过用别名自动装配吗?

# services.yml

services:
    ApiExceptionBundle\YourResponseFactory: ~
    ApiExceptionBundle\Component\Factory\ResponseFactoryInterface:
        alias: ApiExceptionBundle\YourResponseFactory

    ApiExceptionBundle\EventListener\ApiExceptionSubscriber:
        autowire: true

使用 PSR-4 自动发现

或者您可以使用 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+

Symfony 3.4 以来,由于 single-services from your code.

的自动别名,您可以省略别名
# services.yml

services:
    _defaults:
        autowire: true

    ApiExceptionBundle\: ~
        resource: ../ # path to ApiExceptionBundle directory