Symfony-service-container
Symfony-サービスコンテナー
どのアプリケーションでも、オブジェクトはアプリケーションの成長とともに増加する傾向があります。 オブジェクトが増加すると、オブジェクト間の依存関係も増加します。 アプリケーションの成功には、オブジェクトの依存関係を適切に処理する必要があります。
コンポーネントの章で説明したように、Symfonyはオブジェクトの依存関係を処理するための簡単で効率的なコンポーネント DependencyInjection を提供します。 サービスコンテナは、適切に解決された依存関係を持つオブジェクトのコンテナです。 この章では、DependencyInjectionコンポーネントの使用方法を学びましょう。
*Greeter* クラスを作成しましょう。 Greeterクラスの目的は、次の例に示すようにユーザーに挨拶することです。
$greeter = new Greeter('Hi');
$greeter->greet('Jon');//print "Hi, Jon"
Greeterクラスの完全なコードは次のとおりです。
class Greeter {
private $greetingText;
public function __construct($greetingText) {
$this->greetingText = $greetingText;
}
public function greet($name) {
echo $this->greetingText . ", " . $name . "\r\n";
}
}
次に、Greeterクラスをサービスコンテナに追加しましょう。 Symfonyは、新しいコンテナを作成する ContainerBuilder を提供します。 コンテナが作成されると、コンテナのregisterメソッドを使用してGreeterクラスをコンテナに登録できます。
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('Hi');
ここでは、静的な引数を使用して、あいさつ文Hiを指定しています。 symfonyはパラメーターの動的設定も提供します。 動的パラメータを使用するには、名前を選択し、%の間で指定する必要があります。パラメータは、コンテナの setParameter メソッドを使用して設定できます。
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('%greeter.text%');
$container->setParameter('greeter.text', 'Hi');
適切な設定でGreeterクラスを登録しました。 これで、コンテナ get メソッドを使用して、適切に設定されたGreeterオブジェクトを提供するようにコンテナに要求できます。
$greeter = $container->get('greeter');
$greeter->greet('Jon');//prints "Hi, Jon"
Greeterクラスをコンテナに正常に登録し、コンテナから取得して使用しました。 ここで、Greeterクラスを使用する別のクラス User を作成し、それを登録する方法を見てみましょう。
class User {
private $greeter;
public $name;
public $age;
public function setGreeter(\Greeter $greeter) {
$this->greeter = $greeter;
}
public function greet() {
$this->greeter->greet($this->name);
}
}
Userクラスは、セッターメソッドの1つである setGreeter を使用して_Greeter_クラスを取得します。 このシナリオのために、Symfonyはメソッド addMethodCall とクラス Reference を提供して、次のコードに示すように別のクラスを参照します。
use Symfony\Component\DependencyInjection\Reference;
$container
->register('user', 'User')
->addMethodCall('setGreeter', array(new Reference('greeter')));
最後に、 Greeter と User の2つのクラスを登録しました。 これで、次のコードに示すように、適切に設定されたGreeterクラスを持つUserオブジェクトをコンテナから安全にフェッチできます。
$container->setParameter('greeter.text', 'Hi');
$user = $container->get('user');
$user->name = "Jon";
$user->age = 20;
$user->greet();//Prints "Hi, Jon"
PHP自体を使用してコンテナー内のオブジェクトを構成する方法を見てきました。 symfonyは他のメカニズムも提供します。 これらはXMLおよびYAML構成ファイルです。 YAMLを使用してコンテナーを構成する方法を見てみましょう。 そのためには、* symfony/configencyおよび symfony/yaml コンポーネントと symfony/dependency-injection コンポーネントをインストールします。
cd/path/to/dir
mkdir dependency-injection-example
cd dependency-injection-example
composer require symfony/dependency-injection
composer require symfony/config
composer require symfony/yaml
YAML設定は、 services.yml という別のファイルに書き込まれます。 YAML設定は、 parameters と services の2つのセクションで構成されています。 パラメーターセクションでは、すべての必須パラメーターを定義します。 サービスセクションはすべてのオブジェクトを定義します。 サービスセクションは、さらに class、arguments 、 calls という複数のセクションに分かれています。 クラスは、実際のクラスを指定します。 引数は、コンストラクターの引数を指定します。 最後に、呼び出しはセッターメソッドを指定します。 @記号@greeterを使用して別のクラスを参照できます。
parameters:
greeter.text: 'Hello'
services:
greeter:
class: Greeter
arguments: ['%greeter.text%']
user:
class: User
calls:
- [setGreeter, ['@greeter']]
これで、次のコードに示すように、 FileLoader および YamlFileLoader を使用して services.yml をロードおよび構成できます。
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
$yamlContainer = new ContainerBuilder();
$loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__));
$loader->load('services.yml');
$yamlUser = $yamlContainer->get('user');
$yamlUser->name = "Jon";
$yamlUser->age = 25;
$yamlUser->greet();
完全なコードリストは次のとおりです。
main.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
class Greeter {
private $greetingText;
public function __construct($greetingText) {
$this->greetingText = $greetingText;
}
public function greet($name) {
echo $this->greetingText . ", " . $name . "\r\n";
}
}
class User {
private $greeter;
public $name;
public $age;
public function setGreeter(\Greeter $greeter) {
$this->greeter = $greeter;
}
public function greet() {
$this->greeter->greet($this->name);
}
}
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('%greeter.text%');
$container
->register('user', 'User')
->addMethodCall('setGreeter', array(new Reference('greeter')));
$container->setParameter('greeter.text', 'Hi');
$greeter = $container->get('greeter');
$greeter->greet('Jon');
$user = $container->get('user');
$user->name = "Jon";
$user->age = 20;
$user->greet();
$yamlContainer = new ContainerBuilder();
$loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__));
$loader->load('services.yml');
$yamlHello = $yamlContainer->get('greeter');
$yamlHello->greet('Jon');
$yamlUser = $yamlContainer->get('user');
$yamlUser->name = "Jon";
$yamlUser->age = 25;
$yamlUser->greet();
?>
services.yml
parameters:
greeter.text: 'Hello'
services:
greeter:
class: Greeter
arguments: ['%greeter.text%']
user:
class: User
calls:
- [setGreeter, ['@greeter']]
symfony Webフレームワークは、依存性注入コンポーネントを広範囲に使用します。 すべてのコンポーネントは、集中化されたサービスコンテナによってバインドされます。 symfonyのWebフレームワークは、コンテナを container プロパティを介してすべての Controller で公開します。 ロガー、メーラーなど、その中に登録されているすべてのオブジェクトを取得できます。
$logger = $this->container->get('logger');
$logger->info('Hi');
コンテナに登録されているオブジェクトを見つけるには、次のコマンドを使用します。
cd/path/to/app
php bin/console debug:container
インストールの章で作成された hello Webアプリには、約200以上のオブジェクトがあります。