Как получить доступ к параметрам приложения с сервиса?
из моих контроллеров я получаю доступ к параметрам приложения (те, что в /app/config
) С
$this->container->getParameter('my_param')
но я не знаю, как получить доступ к нему из службы (я предполагаю, что мой класс обслуживания не должен расширяться SymfonyBundleFrameworkBundleControllerController
).
Я должен сопоставить необходимые параметры в моей регистрации службы, как это:
#src/Me/MyBundle/Service/my_service/service.yml
parameters:
my_param1: %my_param1%
my_param2: %my_param2%
my_param3: %my_param3%
или что-то подобное? Как получить доступ к параметрам приложения из службы?
этот вопрос похоже на то же самое, но мой на самом деле отвечает на него (параметры от контроллера), я говорю о доступе из службы.
4 ответа:
вы можете передавать параметры в свой сервис так же, как вы вводите другие сервисы, указав их в своем определении сервиса. Например, в YAML:
services: my_service: class: My\Bundle\Service\MyService arguments: [%my_param1%, %my_param2%]
здесь
%my_param1%
etc соответствует параметру с именемmy_param1
. Тогда ваш конструктор класса обслуживания может быть:public function __construct($myParam1, $myParam2) { // ... }
вместо того, чтобы сопоставлять ваши необходимые параметры один за другим, почему бы не разрешить вашему сервису напрямую обращаться к контейнеру? При этом вам не нужно обновлять сопоставление, если добавлены новые параметры (которые относятся к вашему сервису).
для этого:
внесите следующие изменения в свой класс обслуживания
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 } }
добавить @service_container в качестве" аргументов " в ваших службах.в формате YML
services: my_service_id: class: ...\MyServiceClass arguments: ["@service_container"] // <- Add this
Чистый Путь 2018
С 2017 года и Symfony 3.4 есть гораздо более чистый способ-простота установки и использования.
вместо того, чтобы использовать контейнер и сервис/параметр локатор анти-шаблон, вы можете передать параметры в класс через его конструктор. Не волнуйтесь, это не трудоемкая работа, а скорее настройка один раз и забыть подход.
как настроить его в 2 шага?
1.
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. Любой
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" } }
Мгновенное Обновление Готово!
в случае, если вы используете более старый подход, вы можете автоматизировать его с ректором.
Подробнее
это называется инъекция конструктора через локатор служб подход.
читать больше об этом, проверьте мой пост как получить параметр в контроллере Symfony чистым способом.
(это протестировано, и я продолжаю обновлять его для новой версии Symfony major (5, 6...)).
как решение некоторых из упомянутых проблем, я определяю параметр массива, а затем вводим его. Добавление нового параметра позже просто требует добавления в массив параметров без какого-либо изменения аргументов service_container или конструкции.
Так что расширение на @richsage ответ:
параметры.в формате YML
parameters: array_param_name: param_name_1: "value" param_name_2: "value"
услуги.в формате YML
services: my_service: class: My\Bundle\Service\MyService arguments: [%array_param_name%]
тогда доступ внутри класса
public function __construct($params) { $this->param1 = array_key_exists('param_name_1',$params) ? $params['param_name_1'] : null; // ... }