コントローラーから、アプリケーションパラメーター(/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%
などはmy_param1
という名前のパラメーターに対応します。次に、サービスクラスコンストラクターは次のようになります。
public function __construct($myParam1, $myParam2)
{
// ...
}
2017およびSymfony 3.4 以降、はるかにクリーンな方法があります-セットアップと使用が簡単です。
コンテナおよびサービス/パラメータロケータアンチパターンを使用する代わりに、 constructor を介してクラスにパラメータを渡すことができます。心配する必要はありません。時間のかかる作業ではなく、一度セットアップして忘れるアプローチです。
2ステップで設定する方法は?
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: ..
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で自動化 を使用できます。
これは、 constructor injection over services locator アプローチと呼ばれます。
これについての詳細を読むには、私の投稿を確認してください Symfonyコントローラーでパラメーターを取得する方法 。
(テスト済みで、新しいSymfonyメジャーバージョン(5、6 ...)に合わせて更新されています)。
必要なパラメーターを1つずつマッピングする代わりに、サービスがコンテナーに直接アクセスできるようにしてみませんか?そうすることで、(サービスに関連する)新しいパラメーターが追加された場合、マッピングを更新する必要はありません。
そうするために:
サービスクラスに以下の変更を加えます
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
いくつかの問題の解決策として、配列パラメーターを定義してから注入します。後で新しいパラメーターを追加するには、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;
// ...
}
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');
...
}
}
ソース: https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service 。
Symfony 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
Symfony 4では、依存性注入によってパラメーターにアクセスできます:
サービス:
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'