Contoh Dependency Injection dalam PHP Dengan Komponen Symfony
() translation by (you can also view the original English article)
Dalam artikel ini, kita akan melihat beberapa contoh menggunakan komponen Symfony DependencyInjection. Anda akan belajar dasar-dasar dependency Injection, yang memungkinkan lebih bersih dan lebih banyak kode modular, dan Anda akan melihat bagaimana menggunakannya dalam aplikasi PHP Anda dengan Symfony komponen.
Apa yang Dimaksud dengan Komponen Symfony DependencyInjection?
Komponen Symffony DependencyInjection menyediakan cara standar untuk instantiate objek dan menangani manajemen dependensi dalam aplikasi PHP Anda. Inti dari komponen DependencyInjection adalah kontainer yang menyimpan semua layanan yang tersedia dalam aplikasi.
Selama fase bootstrap dari aplikasi Anda, Anda seharusnya mendaftarkan semua layanan dalam aplikasi Anda ke dalam kontainer. Pada tahap selanjutnya, wadah bertanggung jawab untuk membuat layanan seperti yang diperlukan. Lebih penting lagi, wadah ini juga bertanggung jawab untuk menciptakan dan menyuntikkan dependensi layanan.
Manfaat dari pendekatan ini adalah Anda tidak perlu melakukan hard code pada proses instantiating objek karena dependensi akan terdeteksi dan disuntikkan secara otomatis. Ini menciptakan kopling longgar di antara bagian-bagian aplikasi Anda.
Dalam artikel ini, kita akan mengeksplorasi bagaimana Anda dapat mengeluarkan kekuatan komponen DependencyInjection. Seperti biasa, kita akan mulai dengan instalasi dan petunjuk konfigurasi, dan kami akan menerapkan beberapa contoh nyata untuk menunjukkan konsep-konsep kunci.
Instalasi dan Konfigurasi
Di bagian ini, kita akan melanjutkan dan menginstal komponen DependencyInjection. Saya berasumsi bahwa Anda telah menginstal Composer di sistem Anda karena kami memerlukannya untuk menginstal komponen DependencyInjection yang tersedia di Packagist.
Jadi lanjutkan dan menginstal komponen DependencyInjection menggunakan perintah berikut.
1 |
$composer require symfony/dependency-injection
|
Yang harus dibuat file composer.json, yang akan terlihat seperti ini:
1 |
{
|
2 |
"require": { |
3 |
"symfony/dependency-injection": "^4.1", |
4 |
}
|
5 |
}
|
Kita juga akan memasang beberapa komponen lain yang akan berguna dalam contoh Kita.
Jika Anda ingin memuat layanan dari file YAML daripada mendefinisikannya dalam kode PHP, itu adalah komponen Yaml yang datang untuk menyelamatkan karena membantu Anda untuk mengubah string YAML ke tipe data yang kompatibel dengan PHP dan sebaliknya.
1 |
$composer require symfony/yaml
|
Akhirnya, kita akan menginstal komponen Config yang menyediakan beberapa utilitas kelas untuk menginisialisasi dan berurusan dengan nilai-nilai konfigurasi yang didefinisikan dalam berbagai jenis file seperti YAML, INI dan XML. Dalam kasus kami, kami akan menggunakannya untuk memuat layanan dari YAML file.
1 |
$composer require symfony/config
|
Mari kita memodifikasi file composer.json agar terlihat seperti yang berikut.
1 |
{
|
2 |
"require": { |
3 |
"symfony/dependency-injection": "^4.1", |
4 |
"symfony/config": "^4.1", |
5 |
"symfony/yaml": "^4.1" |
6 |
},
|
7 |
"autoload": { |
8 |
"psr-4": { |
9 |
"Services\\": "src" |
10 |
},
|
11 |
"classmap": ["src"] |
12 |
}
|
13 |
}
|
Karena kita telah menambahkan entri classmap baru, mari kita lanjutkan dan memperbarui autoloader komposer dengan menjalankan perintah berikut.
1 |
$composer dump -o |
Sekarang, Anda dapat menggunakan namespace Services
untuk autoload kelas di bawah src directory.
Jadi itulah bagian instalasi, tetapi bagaimana Anda menggunakannya? Pada kenyataannya, itu hanya masalah termasuk file autoload.php yang dibuat oleh Komposer dalam aplikasi Anda, seperti yang ditunjukkan pada cuplikan berikut.
1 |
<?php
|
2 |
require_once './vendor/autoload.php'; |
3 |
|
4 |
// application code
|
5 |
?>
|
Cara Bekerja dengan Kontainer
Di bagian ini, kita akan membahas contoh untuk menunjukkan bagaimana Anda bisa menyuntikkan layanan ke dalam sebuah kontainer. Kontainer harus bertindak sebagai repositori sentral yang menyimpan semua layanan dalam aplikasi Anda. Kemudian, kita bisa menggunakan kontainer untuk mengambil layanan sesuai kebutuhan.
Memulai dengan, mari kita lanjutkan dan menentukan layanan yang cukup mendasar di src / DemoService.php dengan konten berikut.
1 |
<?php
|
2 |
// src/DemoService.php
|
3 |
namespace Services; |
4 |
|
5 |
class DemoService |
6 |
{
|
7 |
public function helloWorld() |
8 |
{
|
9 |
return "Hello World!\n"; |
10 |
}
|
11 |
}
|
Ini adalah layanan yang sangat sederhana yang hanya mengimplementasikan metode helloWorld
untuk saat ini.
Kemudian, lanjutkan dan buat file basic_container.php dengan konten berikut di root aplikasi Anda.
1 |
<?php
|
2 |
// basic_container.php
|
3 |
require_once './vendor/autoload.php'; |
4 |
use Symfony\Component\DependencyInjection\ContainerBuilder; |
5 |
|
6 |
// init service container
|
7 |
$containerBuilder = new ContainerBuilder(); |
8 |
|
9 |
// add service into the service container
|
10 |
$containerBuilder->register('demo.service', '\Services\DemoService'); |
11 |
|
12 |
// fetch service from the service container
|
13 |
$demoService = $containerBuilder->get('demo.service'); |
14 |
echo $demoService->helloWorld(); |
Untuk memulainya, kita menginisialisasi objek ContainerBuilder
dengan konstruktor new ContainerBuilder().
Selanjutnya, kita menggunakan metode register
objek ContainerBuilder
untuk menyuntikkan layanan kustom kita\ Services \ DemoService
ke dalam kontainer. Demo.service
bertindak sebagai alias ke layanan kita.
Akhirnya, kita menggunakan metode get
objek ContainerBuilder
untuk mengambil layanan kita dari kotainer dan menggunakannya untuk memanggil metode helloWorl.
Jadi itu adalah demonstrasi dasar tentang cara bekerja dengan kontainer. Di bagian selanjutnya, kita akan memperluas contoh ini untuk mengeksplorasi bagaimana dependensi kelas diselesaikan menggunakan kontainer.
Contoh Dunia Nyata
Di bagian ini, kita akan membuat contoh yang menunjukkan bagaimana dependensi kelas diselesaikan menggunakan komponen DependencyInjection.
Untuk mendemonstrasikannya, kita akan membuat layanan baru DependentService
yang membutuhkan layanan DemoService
, dibuat di bagian sebelumnya, sebagai dependency. Jadi, kita akan melihat bagaimana layanan DemoService
disuntikkan secara otomatis sebagai dependency ketika layanan DependentService
dibuat.
Lanjutkan dan buat file src / DependentService.php dengan konten berikut untuk menentukan layanan DependentService
.
1 |
<?php
|
2 |
// src/DependentService.php
|
3 |
namespace Services; |
4 |
|
5 |
class DependentService |
6 |
{
|
7 |
private $demo_service; |
8 |
|
9 |
public function __construct(\Services\DemoService $demoService) |
10 |
{
|
11 |
$this->demo_service = $demoService; |
12 |
}
|
13 |
|
14 |
public function helloWorld() |
15 |
{
|
16 |
return $this->demo_service->helloWorld(); |
17 |
}
|
18 |
}
|
Seperti yang Anda lihat, layanan \ Services \ DemoService
diperlukan untuk memberi contoh layanan DependentService
.
Selanjutnya, lanjutkan dan buat file di_container.php dengan konten berikut.
1 |
<?php
|
2 |
// di_container.php
|
3 |
require_once './vendor/autoload.php'; |
4 |
use Symfony\Component\DependencyInjection\ContainerBuilder; |
5 |
use Symfony\Component\DependencyInjection\Reference; |
6 |
|
7 |
// init service container
|
8 |
$containerBuilder = new ContainerBuilder(); |
9 |
|
10 |
// add demo service into the service container
|
11 |
$containerBuilder->register('demo.service', '\Services\DemoService'); |
12 |
|
13 |
// add dependent service into the service container
|
14 |
$containerBuilder->register('dependent.service', '\Services\DependentService') |
15 |
->addArgument(new Reference('demo.service')); |
16 |
|
17 |
// fetch service from the service container
|
18 |
$dependentService = $containerBuilder->get('dependent.service'); |
19 |
echo $dependentService->helloWorld(); |
Kita menggunakan metode register
yang sama untuk menyuntikkan layanan kustom kita\ Services \ DependentService
ke dalam kontainer.
Selain itu, kita juga menggunakan metode addArgument
untuk menginformasikan kontainer tentang dependency layanan DependentService
. Kita telah menggunakan kelas Reference
untuk menginformasikan kontainer yang diperlukan untuk menyuntikkan layanan demo.service
ketika layanan dependent.service
diinisialisasi. Dengan cara itu, dependency secara otomatis disuntikkan sesuai kebutuhan!
Akhirnya, kita telah menggunakan metode get
dari object ContainerBuilder
untuk mengambil layanan dependent.service
dari object ContainerBuilder
dan menggunakannya untuk memanggil metode helloWorld
.
Dengan cara ini, komponen DependencyInjection menyediakan cara standar untuk instantiate objek dan menyuntikkan dependensi dalam aplikasi Anda.
Cara Dynamically Load Services Menggunakan File YAML
Dalam bagian terakhir ini, kita akan mengeksplorasi bagaimana Anda dapat secara dinamis memuat layanan dari YAML file. Pada dasarnya, kita akan memperbarui contoh yang dibahas dalam bagian sebelumnya.
Selain komponen DependencyInjection, kita juga akan membutuhkan dua komponen Symfony lainnya untuk menerapkan contoh YAML — Config dan Yaml. Ingat bahwa kita telah menginstal kedua komponen ini di bagian Installation and Configuration bersama dengan komponen DependencyInjection itu sendiri. Jadi kita siap untuk memulai!
Lanjutkan dan buat file services.yaml dengan konten berikut di root aplikasi Anda.
1 |
services: |
2 |
demo.service: |
3 |
class: \Services\DemoService |
4 |
dependent.service: |
5 |
class: \Services\DependentService |
6 |
arguments: ["@demo.service"] |
Seperti yang Anda lihat, itu cukup mudah untuk mendefinisikan layanan menggunakan sintaks YAML. Untuk menentukan dependensi layanan Anda, Anda harus menggunakan kunci arguments
.
Selanjutnya, lanjutkan dan buat file di_yaml_container.php dengan konten berikut.
1 |
<?php
|
2 |
// di_yaml_container.php
|
3 |
require_once './vendor/autoload.php'; |
4 |
use Symfony\Component\DependencyInjection\ContainerBuilder; |
5 |
use Symfony\Component\Config\FileLocator; |
6 |
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; |
7 |
|
8 |
// init service container
|
9 |
$containerBuilder = new ContainerBuilder(); |
10 |
|
11 |
// init yaml file loader
|
12 |
$loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__)); |
13 |
|
14 |
// load services from the yaml file
|
15 |
$loader->load('services.yaml'); |
16 |
|
17 |
// fetch service from the service container
|
18 |
$serviceOne = $containerBuilder->get('dependent.service'); |
19 |
echo $serviceOne->helloWorld(); |
Semuanya hampir sama kecuali bahwa kita memuat layanan dari file services.yaml daripada mendefinisikannya dalam kode PHP itu sendiri. Ini memungkinkan ketergantungan aplikasi untuk didefinisikan secara dinamis.
Kesimpulan
Komponen Symffony DependencyInjection menjadi pusat perhatian dalam tutorial ini. Kami melihat cara memasang dan mengonfigurasi DependencyInjection, serta beberapa contoh dunia nyata tentang bagaimana hal itu dapat digunakan.
Saya benar-benar terpesona dan bersemangat tentang komponen yang dipisahkan dari framework Symfony yang dapat Anda pilih untuk aplikasi Anda. Masukkan mereka ke kode Anda dan mereka hanya berfungsi! Secara keseluruhan, saya hanya dapat melihat manfaat dari pendekatan kerangka kerja baru ini untuk komunitas PHP kita!
Bagikan pemikiran dan saran Anda menggunakan umpan di bawah ini. Saya ingin berdiskusi dengan Anda lebih lanjut!