web-dev-qa-db-ja.com

サービスからアプリケーションパラメータにアクセスする方法

コントローラーから、アプリケーションパラメーター(/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%

または何か似たような?サービスからアプリケーションパラメータにアクセスするにはどうすればよいですか?


この質問 は同じように見えますが、実際に私の答えは(コントローラーからのパラメーター)、サービスからアクセスすることです。

68

サービス定義でパラメーターを指定することにより、他のサービスを注入するのと同じ方法でパラメーターをサービスに渡すことができます。たとえば、YAMLの場合:

services:
    my_service:
        class:  My\Bundle\Service\MyService
        arguments: [%my_param1%, %my_param2%]

%my_param1%などはmy_param1という名前のパラメーターに対応します。次に、サービスクラスコンストラクターは次のようになります。

public function __construct($myParam1, $myParam2)
{
    // ...
}
113
richsage

クリーンウェイ2018

2017およびSymfony 3.4 以降、はるかにクリーンな方法があります-セットアップと使用が簡単です。

コンテナおよびサービス/パラメータロケータアンチパターンを使用する代わりに、 constructor を介してクラスにパラメータを渡すことができます。心配する必要はありません。時間のかかる作業ではなく、一度セットアップして忘れるアプローチです。

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"
    }
}

インスタントアップグレード準備完了!

古いアプローチを使用する場合は、 Rectorで自動化 を使用できます。

続きを読む

これは、 constructor injection over services locator アプローチと呼ばれます。

これについての詳細を読むには、私の投稿を確認してください Symfonyコントローラーでパラメーターを取得する方法

(テスト済みで、新しいSymfonyメジャーバージョン(5、6 ...)に合わせて更新されています)。

20
Tomáš Votruba

必要なパラメーターを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
18
Ham L.

いくつかの問題の解決策として、配列パラメーターを定義してから注入します。後で新しいパラメーターを追加するには、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;
    // ...
}
6
Dave

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

3
Ousmane

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

2

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'
0
shades3002