【问题标题】:Symfony 3.3 - Services.yml Argument (ResponseFactory) - Parameter Being Passed In As String Instead of ObjectSymfony 3.3 - Services.yml 参数(ResponseFactory) - 参数作为字符串而不是对象传入
【发布时间】:2018-02-01 23:43:44
【问题描述】:

错误

您好,我收到以下错误:

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 参数分配的开头实际上有一个 @ 符号。 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. @ 符号有什么作用?猜测一下,我认为它告诉代码实例化引用的类的对象,而不是仅仅使用字符串。对吗?

【问题讨论】:

  • 您确实需要@ 符号来注入服务而不是字符串。你确定 ApiExceptionBundle\Component\... 是正确的吗?我怀疑它实际上是 ApiExceptionBundle\Factory\ResponseFactory。还需要更改构造函数。您的 IDE 应该会告诉您是否有正确的类名。如果删除 Component 部分实际上是解决方案,那么您可能根本不需要 services.yml 条目。
  • 您还需要在 services.yml 文件中设置 $debug。
  • 感谢您的回复和解释@符号的含义 Cerad。我最终使用了 Tomáš 在下面发布的建议,它最终奏效了。我保留了“组件”部分,因为这就是路径的结构。至于 $debug 条目,我已经在 services.yml 中有它(即参数部分中的 $debug: '%kernel.debug%' ),但为了简化一些事情,我把它从我的问题中删除了。跨度>

标签: php symfony dependency-injection factory subscriber


【解决方案1】:

对于 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

【讨论】:

  • 这为我解决了这个问题。谢谢!
  • @khgm13 太棒了,我还使用 PSR-4 添加了更简单的解决方案。
  • 还有 Symfony 3.4 版本
  • 谢谢!这将在我们将来升级 Symfony 版本时有所帮助。
猜你喜欢
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 2020-12-23
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 2013-10-08
  • 1970-01-01
相关资源
最近更新 更多