From my controllers, I access the application parameters (those in /app/config
) with
$this->container->getParameter('my_param')
But I don't know how to access it from a service (I imagine my service class is not supposed to extend Symfony\Bundle\FrameworkBundle\Controller\Controller
).
Should I map needed parameters into my service registration like this:
#src/Me/MyBundle/Service/my_service/service.yml
parameters:
my_param1: %my_param1%
my_param2: %my_param2%
my_param3: %my_param3%
or something similar? How should I access to my application parameters from a service?
This question seems like the same but mine actually answers to it (parameters from a controller), I'm talking about accessing 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)
{
// ...
}
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?
config.yml
# config.yml
parameters:
api_pass: 'secret_password'
api_user: 'my_name'
services:
_defaults:
autowire: true
bind:
$apiPass: '%api_pass%'
$apiUser: '%api_user%'
App\:
resource: ..
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"
}
}
In case you use older approach, you can automate it with Rector.
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...)).
There is a very clean new way to achieve it since symfony 4.1
<?php
// src/Service/MessageGeneratorService.php
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class MessageGeneratorService
{
private $params;
public function __construct(ParameterBagInterface $params)
{
$this->params = $params;
}
public function someMethod()
{
$parameterValue = $this->params->get('parameter_name');
...
}
}
source : https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With