How to access application settings from a service?

From my controllers, I access application settings (in /app/config ) with

 $this->container->getParameter('my_param') 

But I do not know how to access it from the service (I believe that my class of service should not extend Symfony\Bundle\FrameworkBundle\Controller\Controller ).

Do I have to display the necessary parameters in my service registration as follows:

 #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 do I access my application settings from a service?




This question seems the same, but mine actually answers it (parameters from the controller), I'm talking about access from the service.

+67
php yaml symfony
Jun 26 2018-12-12T00:
source share
8 answers

You can pass parameters to your service in the same way as 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 %my_param1% etc. matches a parameter named my_param1 . Then your class of service constructor might be as follows:

 public function __construct($myParam1, $myParam2) { // ... } 
+113
Jun 26 '12 at 16:17
source share

Instead of matching the necessary parameters one by one, why don't you let your service access the container directly? However, you do not need to update your mapping if new parameters are added (which apply to your service).

For this:

Make the following changes to the class of service

 use Symfony\Component\DependencyInjection\ContainerInterface; // <- Add this class 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 
+19
07 Sep '15 at 9:16
source share

Clean Way 2018

Since 2017 and Symfony 3.4 there is a much cleaner way - it's easy to configure and use.

Instead of using the anti-template of the container and service / parameter, you can pass parameters to the class through the constructor . Do not worry, this is not a time-consuming job, but setting the time and forget it.

How to configure it in 2 steps?

config.yml

 # 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: .. 

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 is ready!

If you are using an older approach, you can automate it with the help of a rector .

Read more

This is called installing the constructor using the service localization method.

To learn more about this, check out my post. How to get the parameter in the Symfony Controller "Clean Path" .

(It has been tested and I am updating it for the new version of Symfony (5, 6 ...)).

+17
Mar 03 '18 at 13:02
source share

As a solution to some of the problems mentioned, I define an array parameter and then insert it. Adding a new parameter later simply requires adding parameters to the array without any changes to the arguments or the service_container construct.

So, we continue to answer @richsage:

parameters.yml

 parameters: array_param_name: param_name_1: "value" param_name_2: "value" 

services.yml

 services: my_service: class: My\Bundle\Service\MyService arguments: [%array_param_name%] 

Then go inside the class

 public function __construct($params) { $this->param1 = array_key_exists('param_name_1',$params) ? $params['param_name_1'] : null; // ... } 
+6
Nov 16 '16 at 19:51
source share

Starting with Symfony 4.1, there is a whole new way to achieve this.

 <?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 .

+3
Nov 06 '18 at 12:56
source share

With Symfony 4.1, the solution is quite simple.

Here is a snippet of the original post:

 // src/Service/MessageGenerator.php // ... use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; class MessageGenerator { private $params; public function __construct(ParameterBagInterface $params) { $this->params = $params; } public function someMethod() { $parameterValue = $this->params->get('parameter_name'); // ... } } 

Link to the original post: https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service

+2
Oct 24 '18 at 12:12
source share

In Symfony 4, we can access parameters by using dependency injection:

Services:

  use Symfony\Component\DependencyInjection\ContainerInterface as Container; MyServices { protected $container; protected $path; public function __construct(Container $container) { $this->container = $container; $this->path = $this->container->getParameter('upload_directory'); } } 

parameters.yml:

 parameters: upload_directory: '%kernel.project_dir%/public/uploads' 
0
May 22 '19 at
source share

Symfony 3.4 is here.

After some research, I don’t think passing parameters to the class / service through the constructor is always a good idea. Imagine if you need to pass a few more parameters to the controller / service than 2 or 3. What then? It would be ridiculous to pass, for example, up to 10 parameters.

Instead, use the ParameterBag class as a dependency, declaring the service in yml, and then use as many parameters as you want.

For a specific example, let's say you have a mailing list service such as PHPMailer, and you want to have PHPMailer connection parameters in the paramters.yml file:

 #parameters.yml parameters: mail_admin: abc@abc.abc mail_host: mail.abc.com mail_username: noreply@abc.com mail_password: pass mail_from: contact@abc.com mail_from_name: contact@abc.com mail_smtp_secure: 'ssl' mail_port: 465 #services.yml services: app.php_mailer: class: AppBundle\Services\PHPMailerService arguments: ['@assetic.parameter_bag'] #here one could have other services to be injected public: true # AppBundle\Services\PHPMailerService.php ... use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; ... class PHPMailerService { private $parameterBag; private $mailAdmin; private $mailHost; private $mailUsername; private $mailPassword; private $mailFrom; private $mailFromName; private $mailSMTPSecure; private $mailPort; } public function __construct(ParameterBag $parameterBag) { $this->parameterBag = $parameterBag; $this->mailAdmin = $this->parameterBag->get('mail_admin'); $this->mailHost = $this->parameterBag->get('mail_host'); $this->mailUsername = $this->parameterBag->get('mail_username'); $this->mailPassword = $this->parameterBag->get('mail_password'); $this->mailFrom = $this->parameterBag->get('mail_from'); $this->mailFromName = $this->parameterBag->get('mail_from_name'); $this->mailSMTPSecure = $this->parameterBag->get('mail_smtp_secure'); $this->mailPort = $this->parameterBag->get('mail_port'); } public function sendEmail() { //... } 

I think this is the best way.

-one
Oct 17 '18 at 20:44
source share



All Articles