Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to pass parameter to service in Symfony 3.3

Tags:

php

symfony

I am use a parameter in my service with Symfony 3.3 but I keep getting the error.

Error

[Symfony\Component\DependencyInjection\Exception\AutowiringFailedException] Cannot autowire service "AppBundle\Service\ApiInterface": argument "$api_endpoint" of method "__construct()" must have a type-hint or be given a value explicitly.

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!

like image 660
gameofcode Avatar asked Oct 11 '17 10:10

gameofcode


1 Answers

The problem is that you have 2 different services :app.service.api_interface and AppBundle\Service\ApiInterface. The first is good configured, the second is not.

If you necessarily need the app.service.api_interface service, you can change your configuration in order to have the first as an alias of the second like this :

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

With your config, you do not configure the AppBundle\Service\ApiInterface service, but you configure the app.service.api_interface service. With my suggestion, you configure the 2 services.

If you do not need app.service.api_interface service, you can only let one service :

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

This declaration overrides the AppBundle\Service\ApiInterfaceservice. You can override any service that's imported by using its id (class name) below : It's preferable to move this overriding below the AppBundle\ declaration.

Final file can be like this :

#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%"

Documentation : manually wiring arguments

Documentation : explicitly configuring services and arguments

In addition, I suggest you to remove the space of the parameter name %endpoint test% (and rename it to %endpoint_test% for example)

like image 160
Arno Avatar answered Nov 13 '22 21:11

Arno