내 컨트롤러에서 나는 응용 프로그램 매개 변수 (에서와 액세스 /app/config
)과을
$this->container->getParameter('my_param')
하지만 서비스에서 액세스하는 방법을 모르겠습니다 (내 서비스 클래스가 확장되지 않아야한다고 생각합니다 Symfony\Bundle\FrameworkBundle\Controller\Controller
).
다음과 같이 필요한 매개 변수를 서비스 등록에 매핑해야합니까?
#src/Me/MyBundle/Service/my_service/service.yml
parameters:
my_param1: %my_param1%
my_param2: %my_param2%
my_param3: %my_param3%
또는 비슷한 것? 서비스에서 내 애플리케이션 매개 변수에 어떻게 액세스해야합니까?
이 질문 은 똑같아 보이지만 실제로 대답합니다 (컨트롤러의 매개 변수), 서비스에서 액세스하는 것에 대해 이야기하고 있습니다.
답변
서비스 정의에서 매개 변수를 지정하여 다른 서비스를 삽입하는 것과 동일한 방식으로 서비스에 매개 변수를 전달할 수 있습니다. 예를 들어 YAML에서 :
services:
my_service:
class: My\Bundle\Service\MyService
arguments: [%my_param1%, %my_param2%]
여기서 %my_param1%
etc는라는 매개 변수에 해당합니다 my_param1
. 그러면 서비스 클래스 생성자가 다음과 같을 수 있습니다.
public function __construct($myParam1, $myParam2)
{
// ...
}
답변
클린 웨이 2018
2018 년과 Symfony 3.4 이후 훨씬 더 깔끔한 방법이 있습니다. 설정과 사용이 쉽습니다.
컨테이너 및 서비스 / 매개 변수 로케이터 안티 패턴을 사용하는 대신 constructor를 통해 매개 변수를 클래스에 전달할 수 있습니다 . 걱정하지 마세요. 시간이 많이 걸리는 작업이 아니라 한 번 설정하고 접근을 잊어 버립니다 .
2 단계로 설정하는 방법은 무엇입니까?
1. 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"
}
}
즉시 업그레이드 준비!
이전 접근 방식을 사용하는 경우 Rector 를 사용하여 자동화 할 수 있습니다 .
더 읽어보기
이를 서비스 로케이터 접근 방식에 대한 생성자 주입 이라고 합니다.
이에 대해 자세히 알아 보려면 내 게시물 How to Get Parameter in Symfony Controller the Clean Way를 확인하십시오 .
(테스트를 거쳐 새로운 Symfony 메이저 버전 (5, 6 …)에 대해 계속 업데이트합니다.)
답변
필요한 매개 변수를 하나씩 매핑하는 대신 서비스가 컨테이너에 직접 액세스하도록 허용하지 않는 이유는 무엇입니까? 이렇게하면 서비스와 관련된 새 매개 변수가 추가 된 경우 매핑을 업데이트 할 필요가 없습니다.
그렇게하려면 :
서비스 클래스를 다음과 같이 변경하십시오.
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
}
}
services.yml에서 @service_container를 “인수”로 추가하십시오.
services:
my_service_id:
class: ...\MyServiceClass
arguments: ["@service_container"] // <- Add this
답변
심포니 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');
...
}
}
출처 : https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service .
답변
언급 된 몇 가지 문제에 대한 해결책으로 배열 매개 변수를 정의한 다음 삽입합니다. 나중에 새 매개 변수를 추가하려면 service_container 인수 또는 구성을 변경하지 않고 매개 변수 배열에 추가하기 만하면됩니다.
그래서 @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%]
그런 다음 클래스 내부에 액세스
public function __construct($params)
{
$this->param1 = array_key_exists('param_name_1',$params)
? $params['param_name_1'] : null;
// ...
}
답변
함께 심포니 4.1 솔루션은 매우 간단합니다.
다음은 원본 게시물의 일부입니다.
// 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');
// ...
}
}
원본 게시물 링크 :
https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service
답변
@richsage는 정확하지만 (Symfony 3.?) 내 Symfony 4.x에서는 작동하지 않았습니다. 여기에 Symfony 4가 있습니다.
services.yaml 파일
parameters:
param1: 'hello'
Services:
App\Service\routineCheck:
arguments:
$toBechecked: '%param1%' # argument must match in class constructor
서비스 클래스 routineCheck.php 파일에서 이렇게 생성자를 수행하십시오.
private $toBechecked;
public function __construct($toBechecked)
{
$this->toBechecked = $toBechecked;
}
public function echoSomething()
{
echo $this->toBechecked;
}
끝난.