Symfony - Hizmet Kabı

Herhangi bir uygulamada, nesneler uygulama büyüdükçe artma eğilimindedir. Nesneler arttıkça, nesneler arasındaki bağımlılık da artar. Başarılı bir uygulama için nesne bağımlılığının düzgün bir şekilde ele alınması gerekir.

Bileşenler bölümünde tartışıldığı gibi, Symfony kolay ve verimli bir bileşen sağlar, DependencyInjectionnesne bağımlılığını işlemek için. Hizmet kapsayıcısı, aralarında uygun şekilde çözülmüş bağımlılığa sahip nesnelerden oluşan bir kapsayıcıdır. Bu bölümde DependencyInjection bileşeninin nasıl kullanılacağını öğrenelim.

Bir yaratalım Greetersınıf. Greeter sınıfının amacı, aşağıdaki örnekte gösterildiği gibi kullanıcıyı selamlamaktır.

$greeter = new Greeter('Hi'); 
$greeter->greet('Jon'); // print "Hi, Jon"

Greeter sınıfının tam kodu aşağıdaki gibidir.

class Greeter { 
   private $greetingText; 
   
   public function __construct($greetingText) { 
      $this->greetingText = $greetingText; 
   }  
   public function greet($name) { 
      echo $this->greetingText . ", " . $name . "\r\n"; 
   } 
}

Şimdi servis konteynerine Greeter sınıfını ekleyelim. Symfony sağlarContainerBuilderyeni bir kap oluşturmak için. Kapsayıcı oluşturulduktan sonra, Greeter sınıfı, kapsayıcının kayıt yöntemi kullanılarak içine kaydedilebilir.

use Symfony\Component\DependencyInjection\ContainerBuilder; 
$container = new ContainerBuilder(); 
$container 
   ->register('greeter', 'Greeter') 
   ->addArgument('Hi');

Burada, selamlama metni Hi'yi belirtmek için statik bağımsız değişken kullandık. Symfony, dinamik bir parametre ayarı da sağlar. Dinamik bir parametre kullanmak için, bir isim seçmemiz ve bunu% arasında belirtmemiz gerekir ve parametre, kapsayıcı kullanılarak ayarlanabilirsetParameter yöntem.

$container = new ContainerBuilder(); 
$container 
   ->register('greeter', 'Greeter') 
   ->addArgument('%greeter.text%');  
$container->setParameter('greeter.text', 'Hi');

Uygun ayarlarla bir Greeter sınıfı kaydettirdik. Şimdi, konteynerden konteyneri kullanarak uygun şekilde yapılandırılmış bir Greeter nesnesi sağlamasını isteyebiliriz.get yöntem.

$greeter = $container->get('greeter'); 
$greeter->greet('Jon'); // prints "Hi, Jon"

Bir sınıfı başarıyla kaydettik, Greeter konteynere, konteynırdan getirdik ve kullandık. Şimdi başka bir sınıf oluşturalımUser, Greeter sınıfını kullanan ve nasıl kaydedileceğini gö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); 
   } 
}

User sınıfı , setter yönteminden birini kullanarak Greeter sınıfını alır ,setGreeter. Bu senaryo için Symfony bir yöntem sağlar,addMethodCall ve bir sınıf Reference aşağıdaki kodda gösterildiği gibi başka bir sınıfa başvurmak için.

use Symfony\Component\DependencyInjection\Reference;  
$container 
   ->register('user', 'User') 
   ->addMethodCall('setGreeter', array(new Reference('greeter')));

Son olarak, iki sınıf kaydettik, Greeter ve Useraralarında güçlü bir ilişki olması. Şimdi, aşağıdaki kodda gösterildiği gibi, uygun şekilde yapılandırılmış Greeter sınıfına sahip User nesnesini konteynerden güvenle getirebiliriz.

$container->setParameter('greeter.text', 'Hi'); 
$user = $container->get('user'); 
$user->name = "Jon"; 
$user->age = 20; 
$user->greet(); // Prints "Hi, Jon"

PHP'nin kendisini kullanarak bir konteynerdeki bir nesneyi nasıl yapılandıracağımızı gördük. Symfony başka mekanizmalar da sağlar. XML ve YAML yapılandırma dosyalarıdır. YAML kullanarak bir kapsayıcıyı nasıl yapılandıracağımızı görelim. Bunun için kursymfony/config ve symfony/yaml ile birlikte bileşenler symfony/dependency-injection bileşenleri.

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 yapılandırması ayrı bir dosyaya yazılacak, services.yml. YAML yapılandırması iki bölümden oluşur,parameters ve services. Parametreler bölümü, gerekli tüm parametreleri tanımlar. Hizmetler bölümü tüm nesneleri tanımlar. Hizmetler bölümü ayrıca birden fazla bölüme ayrılmıştır:class, arguments, ve calls. Sınıf, gerçek sınıfı belirtir. Bağımsız değişkenler, yapıcının bağımsız değişkenlerini belirtir. Son olarak, çağrılar ayarlayıcı yöntemlerini belirtir. Başka bir sınıfa @ simgesi, @greeter kullanılarak başvurulabilir.

parameters: 
   greeter.text: 'Hello' 
services: 
   greeter: 
      class: Greeter
      arguments: ['%greeter.text%'] 
   user: 
      class: User 
      calls: 
         - [setGreeter, ['@greeter']]

Şimdi, services.yml kullanılarak yüklenebilir ve yapılandırılabilir FileLoader ve YamlFileLoader aşağıdaki kodda gösterildiği gibi.

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();

Tam kod listesi aşağıdaki gibidir.

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 çerçevesi, bağımlılık ekleme bileşenini yoğun bir şekilde kullanır. Tüm bileşenler, merkezi servis konteyneri tarafından bağlanır. Symfony web çerçevesi kapsayıcıyı tümController vasıtasıyla containerEmlak. İçinde kayıtlı olan tüm nesneleri, örneğin logger, maililer vb. Üzerinden alabiliriz.

$logger = $this->container->get('logger'); 
$logger->info('Hi');

Konteynere kayıtlı nesneyi bulmak için aşağıdaki komutu kullanın.

cd /path/to/app 
php bin/console debug:container

Yaklaşık 200+ nesne var hello kurulum bölümünde oluşturulan web uygulaması.