Quick Start Symfony DI (Dependency Injection) Tutorial
Apakah Ketergantungan Injection (DI)?
Ketergantungan suntikan adalah teknik yang membolehkan untuk benda longgar digabungkan dalam aplikasi perisian. Biasanya jika sebuah objek memerlukan akses kepada fungsi lain akan instantiated dalaman yang mengarah ke sistem tightly coupled. Dengan menerapkan injeksi pergantungan kami menyuntikkan benda-benda yang diperlukan sedia untuk digunakan (kadang-kadang juga disebut inversi kawalan - mengikut). Ambil contoh berikut:
<? Php kelas DecisionMaker { fungsi awam makeDecision (array parameter $) { / / Perlu penyesuai database $ Dp baru = DecisionParameters (); $ ParameterScore getScore = $ dp-> ($ parameter); / * ... Beberapa logik lebih keputusan ... * / return ($ parameterScore> 50); } }
Potongan kod ini dikatakan terlepas dari DecisionParameters objek. Menulis semula di atas dalam mode longgar digabungkan kami akan memiliki sesuatu yang seperti ....
<? Php kelas DecisionMaker { private $ _dp; fungsi awam __construct ($ dp) { $ This-> _dp = $ dp; } fungsi awam makeDecision (array parameter $) { $ ParameterScore = $ this-> _dp-> getScore ($ parameter); / * ... Beberapa logik lebih keputusan ... * / return ($ parameterScore> 50); } }
Sementara mendapatkan manfaat dari kod longgar ditambah kita menambah kompleksitas seperti bahawa setiap kali suatu objek instantiated kita juga harus instantiate kebergantungan dan lulus ini dalam juga. Contohnya, ini:
$ Pilihan DecisionMaker = new (); makeDecision echo $ pilihan-> (array ('usaha' => 'rendah', 'kembali' => 'quality'));
kini menjadi:
$ Dp baru = DecisionParameters (); $ Pilihan = baru DecisionMaker ($ dp); makeDecision echo $ pilihan-> (array ('usaha' => 'rendah', 'kembali' => 'quality'));
Situasi ini menjadi lebih menyakitkan sebagai jumlah dependencies untuk kelas meningkat, dan bagaimana jika kebergantungan sendiri memiliki kebergantungan? Hal ini dapat dengan cepat menjadi mimpi buruk pentadbiran objek! Masukkan bekas pergantungan suntikan (atau rangka) ...
Ketergantungan Suntikan Wadah / Rangka
Ketergantungan suntikan kontena (atau rangka) menangani proses penciptaan objek, instantiate dan suntik setiap kebergantungan misalnya sebelum kembali ke pemanggil.
Dalam kod anda daripada membuat objek baru secara langsung kita meminta salinan objek dari bekas DI. Objek kita dikembalikan sudah memiliki semua dependensinya disuntik dan objek siap untuk pergi.
Symfony Dependency Injection Container
Symfony mungkin terkenal kerana penuh mereka stack MVC rangka namun mereka juga mengeluarkan beberapa bahagian yang boleh digunakan secara mandiri. Contohnya, pergantungan suntikan bekas kita akan bicarakan di sini, sebuah YAML parser, mesin template, lihat bahagian Symfony lebih.
The Symfony DI kontena didasarkan pada bahawa dari Spring Framework di Jawa .
Bootstrap
Dalam rangka untuk Bootstrap pergantungan Symfony rangka suntikan kita menggunakan kod yang terdapat di bawah ini. Saya telah memilih untuk menggunakan YAML hanya kerana ia mudah untuk dibaca dan setup. Untuk kelajuan maksimum yang anda mungkin ingin menulis wadah untuk polos PHP (Symfony bekas boleh melakukan ini untuk anda sekali setup), atau alternatif cache turun kontena menggunakan Zend_Cache , atau serupa.
Untuk memasang Symfony DI ikuti arahan yang dibekalkan di sini http://components.symfony-project.org/dependency-injection/installation , dan menambahnya ke jalan anda.
/ / Load Symfony DI kontena memerlukan 'sfServiceContainerBuilder.php'; $ Wadah sfServiceContainerBuilder = new (); $ Loader sfServiceContainerLoaderFileYaml = baru ($ kontena); $ Loader-> load (APPLICATION_PATH '/ config / di / services.yml'.);
Pertama kita instantiate bekas baru, dan kemudian kita load tatarajah kita dari file YAML. Nota: DI bekas boleh memuatkan konfigurasi dari beberapa format seperti XML , YAML, PHP, dan *. INI Saya cenderung untuk menyertakan fail YAML tunggal dan mengimport fail lain dari dalam sana.
Beberapa fail konfigurasi boleh diimport dengan menggunakan format yang berbeza, definisi baru timpa yang telah ditetapkan. File tatarajah boleh memasukkan rujukan kepada objek dan parameter.
* INI hanya mampu mendefinisikan parameter dan tidak mampu untuk mengimport fail lain
Contoh tatarajah
import: - {Sumber: daos.yml} parameter: username: palsu jasa: # Model Pelanggan model.customer: kelas: Pro_Customer Panggilan: - [SetLogger, [@ utils.logger]] - [SetDao, [@ data.userdata.mysql]] - [SetUserName,% username [%]] # Model Produk model.product: kelas: Pro_Product hujah: [% username%, {taip:% accesslevel%, lastlogin:% lastlogin%}] Panggilan: - [SetDao, [@ data.product.mysql]] # Logger utils.logger: kelas: Pro_Logger pengeluar: getInstance Panggilan: - [SetHandle, [@ utils.filewriter]]
Saya fikir kod di atas cukup jelas diri tapi untuk lebih jelas saya akan menjelaskan masing-masing bahagian sekarang.
Pertama kita mendefinisikan beberapa import (misalnya file-file lain untuk mengurai), saya suka ke kumpulan tatarajah saya untuk DAOs misalnya dalam satu fail, utiliti di lain dan nama fail tersebut dengan tepat. Walaupun sedikit lebih lambat itu mempercepatkan penyelenggaraan fail-fail konfigurasi. Syarikat juga membolehkan anda mengurai file format lain yang menggunakan bendera import yang berbeza. File diterangkan dalam rangka dengan definisi baru timpa atau perubahan perkhidmatan yang sebelumnya ditetapkan / parameter.
Selanjutnya kita mendefinisikan parameter, parameter umumnya boleh menjadi semua jenis pembolehubah PHP. Pada titik ini saya tidak tahu apa parameter nama pengguna saya perlu (saya perlu mengesahkan untuk itu!), Jadi saya telah mendefinisikan nilai lalai dan aku akan menimpa nilai itu nanti. Nota, kelas tidak instantiated sampai anda meminta mereka sehingga menentukan parameter sedikit kemudian adalah baik-baik saja. Berikut ini saya mendefinisikan beberapa perkhidmatan:
- Instantiate Pro_Customer, melewati sebuah instance dari logger saya ke setLogger () kaedah, tambah saya MySQL mengakses objek data (DAO), dan lulus dalam username juga. Setiap kali saya meminta objek ini saya ingin contoh baru
- Buat sebuah instance dari Pro_Product, melewati hujah nama pengguna dan pelbagai pilihan untuk pengeluar. Setelah setDao panggilan Instansiasi () dan menyebarkannya produk saya DAO
- Beri aku salinan Pro_Logger, instantiate itu menggunakan getInstance () kaedah dan lulus salinan objek penulis saya fail melalui setHandle () sekali dimuat nya. penulis fail saya ditakrifkan di salah satu import saya.
Dalam fail konfigurasi perkhidmatan direferensi dengan mengawali nama dengan @ 'simbol', parameter yang dirujuk oleh mengawali dan menambah dengan '%' simbol, eg@utils.logger%% username.
Menambahkan data posting loading
Kadang-kadang anda tidak tahu apa nilai parameter harus sehingga anda telah dihidupkan, seperti dengan parameter username kita di atas. Dalam rangka menimpa nilai yang offsetSet () kaedah yang digunakan, terlebih dahulu melewati nama parameter diikuti oleh nilai baru:
$ Wadah-> offsetSet ('username', $ username); Mendapatkan Objek dari kontena
Setelah setup daripada instantiate objek langsung sekarang kita pergi ke kontena DI untuk mendapatkan contoh. Dengan DI Symfony kita sebut getService () kaedah, lewat di sebuah string yang menggambarkan pembolehubah yang akan diambil, misalnya
$ Logger $ bekas-> = getService ('utils.logger'); Ini akan melakukan setara:
$ Logger = Pro_Logger:: getInstance (); $ FileWriter Pro_Writer_FileWriter = new (); $ Logger-> setHandler ($ fileWriter);
Hal ini dimungkinkan untuk menentukan sama ada bekas memiliki sebuah instance dari perkhidmatan dengan memanggil hasService () kaedah, yang mengembalikan nilai boolean.
Its tidak perlu mempunyai akses kepada bekas luar tingkat atas aplikasi anda kerana sekali mengambil sebuah contoh semua kebergantungan yang diperlukan sampai ke kedalaman terdalam dari aplikasi anda sudah setup dan menunggu untuk dipanggil.
Ujian Unit
Ketergantungan suntikan juga mempunyai manfaat tambahan yang membolehkan objek yang akan diuji dalam isolasi. Mengambil kelas contoh DecisionMaker sebelum melaksanakan tatacara suntikan pergantungan hasil ujian kami juga bergantung pada pelaksanaan kelas DecisionParameters.
Jika kelas yang berbeza memberikan hasil DecisionParameters ujian kami boleh mula gagal bukan kerana kesalahan kita sendiri. Menggunakan suntikan pergantungan kita sekarang boleh lulus dalam sebuah objek DecisionParameters yang mengembalikan dikenali / tetap set hasil untuk parameter input tertentu, kita sekarang ujian DecisionMaker di isolasi dari faktor luaran, iaitu jika ujian kami mulai gagal ini bisa langsung dikaitkan dengan sesuatu perubahan di kelas DecisionMakeer. Hal ini sangat penting yang harus anda bergantung data ujian dari database untuk ujian.
Tatarajah Aplikasi
Cara di mana aplikasi anda berperilaku pada pelayan pengeluaran anda pasti akan berbeza daripada setup perkembangan anda. Sebagai contoh, dalam persekitaran pembangunan peringkat pembalakan akan jauh lebih terperinci dari pada sistem pengeluaran. Ketergantungan dengan menukar fail konfigurasi bekas suntikan sedikit (atau parsing fail konfigurasi tambahan) yang mengubah perilaku bergantung pada persekitaran dibuat sederhana.
Berdasarkan jenis mengisyaratkan pada antara muka daripada pelaksanaan semasa menetapkan dependensinya anda syarikat juga mungkin untuk menukar komponen untuk bahagian-bahagian yang serasi dengan beberapa baris YAML atau XML. Misalnya, saat ini anda boleh mengakses database MySQL melalui DAO (Data Access Object), tetapi pada masa anda dapat mengembangkan PDO, Zend_Db, atau Doktrin pelaksanaan DAO ini. Dengan menambah pelaksanaan baru ke dalam fail tatarajah anda tiba-tiba semua benda yang menggunakan implementasi MySQL tua sekarang menggunakan pelaksanaan baru anda tanpa perlu menyerang perut aplikasi anda.
Nota
- Dengan menetapkan berkongsi: benar dalam tatarajah kita selalu diberikan contoh yang sama suatu objek. Hal ini sangat berguna ketika berhadapan dengan benda-benda yang mengandungi sumber kuasa seperti Sambungan database, file handles, dll
- Ada dua kaedah yang kebergantungan boleh disuntik. Salah satunya adalah untuk lulus kebergantungan dengan pengeluar, atau alternatif melalui kaedah setter. Pola yang berlaku umum adalah untuk lulus kebergantungan yang diperlukan melalui constructor dan optionals melalui setter. keutamaan peribadi saya adalah dengan menggunakan setter untuk segalanya, tapi ini ke pemaju individu
Akhirnya ....
Seiring dengan perbincangan singkat tentang suntikan pergantungan dan kelebihan dan kekurangan ini juga telah panduan cepat-mula melaksanakan Symfony Ketergantungan Suntikan Container ... mudah-mudahan anda telah melihat bahawa itu menghairankan cepat dan mudah. Dari sini anda akan boleh mula menggunakan suntikan pergantungan melalui aplikasi anda dan melihat ke menggunakan lebih banyak ciri-ciri canggih (walaupun contoh sederhana merangkumi sebahagian besar fungsi yang anda akan memerlukan). Seperti biasa Aku menunjuk anda ke manual untuk maklumat lebih lanjut.


















































[...] Posting ini telah disebutkan di Twitter oleh Vincent Jousse, Steven Lloyd Watkin. Steven Lloyd Watkin berkata: http://bit.ly/cUO2ov Quick start untuk # pergantungan symfony suntikan rangka # php # zf [...]
Great rencana.
Saya yakin sekarang. Ketika Bootstrap kita memuatkan fail-fail konfigurasi YAML. Jadi, apakah yang mencipta objek untuk semua, yang kita tidak perlukan?
Untuk contoh: Saya mempunyai Sesuatu kelas yang digunakan hanya kadang-kadang. Jadi apakah itu mencipta sebuah objek atau itu cukup pintar untuk me-load melalui fungsi autoload ketika saya memanggil getInstance () method. Saya tidak mendapatkan itu, iaitu mengapa.
Terima kasih
Tidak, kelas hanya diambil ketika mereka pertama kali diperlukan.
Dalam getInstance () contoh kelas adalah instantiated seperti:
$ Class Kelas =:: getInstance ();
Daripada:
$ Class = new Class ();
Umumnya ini digunakan ketika menerapkan pola singleton.
[...] Membiarkan anda menggunakan DI dalam projek anda dengan cara yang mudah. Steven Lloyd Watkin menghabiskan waktunya di menulis tutorial.It cepat bermula 's worth untuk menyebutkan bahawa Symfony DI Container adalah library standalone sedia sebagai [...] Symfony