How to access an application parameters from a service? How to access an application parameters from a service? symfony symfony

How to access an application parameters from a service?


You can pass parameters to your service in the same way as you inject other services, by specifying them in your service definition. For example, in YAML:

services:    my_service:        class:  My\Bundle\Service\MyService        arguments: [%my_param1%, %my_param2%]

where the %my_param1% etc corresponds to a parameter named my_param1. Then your service class constructor could then be:

public function __construct($myParam1, $myParam2){    // ...}


The Clean Way 2018

Since 2018 and Symfony 3.4 there is much cleaner way - easy to setup and use.

Instead of using container and service/parameter locator anti-pattern, you can pass parameters to class via it's constructor. Don't worry, it's not time-demanding work, but rather setup once & forget approach.

How to set it up in 2 steps?

1. config.yml

# config.ymlparameters:    api_pass: 'secret_password'    api_user: 'my_name'services:    _defaults:        autowire: true        bind:            $apiPass: '%api_pass%'            $apiUser: '%api_user%'    App\:        resource: ..

2. Any Controller

<?php declare(strict_types=1);final class ApiController extends SymfonyController{    /**     * @var string      */    private $apiPass;    /**     * @var string     */    private $apiUser;    public function __construct(string $apiPass, string $apiUser)    {        $this->apiPass = $apiPass;        $this->apiUser = $apiUser;    }    public function registerAction(): void    {        var_dump($this->apiPass); // "secret_password"        var_dump($this->apiUser); // "my_name"    }}

Instant Upgrade Ready!

In case you use older approach, you can automate it with Rector.

Read More

This is called constructor injection over services locator approach.

To read more about this, check my post How to Get Parameter in Symfony Controller the Clean Way.

(It's tested and I keep it updated for new Symfony major version (5, 6...)).


Instead of mapping your needed parameters one by one, why not allowing your service to access the container directly? Doing so, you do not have to update your mapping if there is new parameters added (which relate to your service).

To do so:

Make following changes to your service class

use Symfony\Component\DependencyInjection\ContainerInterface; // <- Add thisclass MyServiceClass{    private $container; // <- Add this    public function __construct(ContainerInterface $container) // <- Add this    {        $this->container = $container;    }    public function doSomething()    {        $this->container->getParameter('param_name_1'); // <- Access your param    }}

Add @service_container as "arguments" in your services.yml

services:  my_service_id:    class: ...\MyServiceClass    arguments: ["@service_container"]  // <- Add this