无法将参数传递给Symfony 3.3中的服务

5

我正在使用Symfony 3.3中的服务参数,但是一直收到错误提示。

错误信息

[Symfony\Component\DependencyInjection\Exception\AutowiringFailedException] 无法自动装配服务“AppBundle\Service\ApiInterface”:方法“__construct()”的参数“$api_endpoint”必须具有类型提示或显式给定值。

config.yml

services:
app.security.login_form_authenticator:
    class: AppBundle\Security\LoginFormAuthenticator
    autowire: true
    arguments: ['@doctrine.orm.entity_manager']
app.service.api_interface:
    class: AppBundle\Service\ApiInterface
    arguments:
      $api_endpoint: "%endpoint test%"

_defaults:
    autowire: true
    autoconfigure: true
    public: false

AppBundle\:
    resource: '../../src/AppBundle/*'
    exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

AppBundle\Controller\:
    resource: '../../src/AppBundle/Controller'
    public: true
    tags: ['controller.service_arguments']

ApiInterface.php

use Unirest;

class ApiInterface
{

private $api_endpoint;

public function __construct(string $api_endpoint)
{
    $this->timeout = 1;

    echo 'form apiinterface construct: ' . $api_endpoint;

}

Any help appreciated feel like I am going round in circles in what should be a simple job!


也许缩进不够。你可以尝试使用4个空格来缩进你的参数。 - Fabien Salles
1
参数通常不会有空格,虽然看起来它运行良好,但你可能想要对其进行“lint”检查 - bin/console lint:yaml app(或其他文件路径,如src/)。如果你正在自动编写代码,你可能更喜欢通过类名调用服务,而不是使用'app.service.api_interface'别名。 - Alister Bulman
别名在最后的配置中没有被识别。所以实际上,我认为问题是别名,因为Symfony加载了2个服务。app.service.api_interface是正确的,但不是AppBundle\Service\ApiInterface - Fabien Salles
有趣。我将你的代码复制/粘贴到一个3.3.10示例项目中,一切都按预期工作。你确定你实际的ApiInterface代码与你在问题中发布的匹配吗?或者你的services.yaml文件中有拼写错误。 - Cerad
你能展示一下app.service.api_interface-service在哪里以及如何使用吗?它是否用作另一个服务的参数?还是通过$container->get("app.service.api_interface")获取的? - Arno
尝试将自己的服务定义放在“_defaults”配置之后。 - yceruto
1个回答

4
问题在于你有两个不同的服务:app.service.api_interfaceAppBundle\Service\ApiInterface。第一个配置良好,而第二个则没有。
如果你必须使用 app.service.api_interface 服务,你可以更改你的配置,使第一个服务成为第二个服务的别名,像这样:
app.service.api_interface: '@AppBundle\Service\ApiInterface'
AppBundle\Service\ApiInterface:
    arguments:
        $api_endpoint: "%endpoint test%"

根据您的配置,您没有配置AppBundle\Service\ApiInterface服务,而是配置了app.service.api_interface服务。

我的建议是,您应该同时配置这两个服务。

如果您不需要app.service.api_interface服务,您可以只让一个服务运行:

AppBundle\Service\ApiInterface:
    arguments:
        $api_endpoint: "%endpoint test%" 

这个声明覆盖了AppBundle\Service\ApiInterface服务。 您可以使用其id(类名)覆盖导入的任何服务,如下所示:最好将此覆盖移动到AppBundle\声明之后。

最终文件可能像这样:

#app/config/services.yml
services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

    AppBundle\:
        resource: '../../src/AppBundle/*'
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    app.security.login_form_authenticator: '@AppBundle\Security\LoginFormAuthenticator'
        # autowire: true #Optional, already set in _defaults
        # arguments: ['@doctrine.orm.entity_manager'] # Optional because of autowiring

    app.service.api_interface: '@AppBundle\Service\ApiInterface' 
    AppBundle\Service\ApiInterface:
        arguments:
            $api_endpoint: "%endpoint test%"

文档:手动连接参数

文档:显式配置服务和参数

此外,我建议你移除参数名称%endpoint test%中的空格(例如将其重命名为%endpoint_test%)。


移动事物的操作成功了。最终我只使用了一个服务并手动进行了连接。谢谢你。 - gameofcode
太棒了,这正是我正在寻找的。来得正是时候,我差点就要把屏幕扔出窗外了 :-) - Bananaapple
很高兴知道它对你有用 :-) - Arno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接