حقن التبعية في PHP: دليل بسيط للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

حقن التبعية في PHP: للمبتدئين



تخيل أنك تقوم بتجميع جهاز كمبيوتر. أنت لا تلحم المعالج مباشرة في اللوحة الأم إلى الأبد - بل تقوم بإدخاله في مقبس خاص، بحيث يمكنك استبداله بآخر أقوى عند الحاجة. حقن التبعية (DI) في PHP يعمل بنفس المبدأ: بدلاً من إنشاء التبعيات داخل الفئة، تقوم "بحقنها" من الخارج.



في هذه المقالة، سنشرح ما هو حقن التبعية، ولماذا هو مطلوب، وكيفية تطبيقه في PHP. ستتعلم كيف تجعل كودك مرنًا، قابلاً للاختبار، وسهل الصيانة.



ما هو حقن التبعية بكلمات بسيطة



حقن التبعية هو نمط تصميم (Design Pattern) حيث يتلقى الكائن تبعياته (كائنات أخرى، خدمات) من الخارج، بدلاً من إنشائها بنفسه. بدلاً من كتابة new Database() داخل الفئة، تقوم بتمرير كائن قاعدة بيانات جاهز عبر المُنشئ (Constructor) أو المُحدد (Setter).



دعنا نلقي نظرة على المشكلة التي يحلها DI. تأمل الفئة UserService التي تنشئ اتصالاً بقاعدة البيانات بشكل مباشر:



<?phpclass UserService {    private $db;        public function __construct() {        // ارتباط صارم بتطبيق محدد        $this->db = new MySQLConnection('localhost', 'user', 'pass');    }        public function getUser($id) {        return $this->db->query("SELECT * FROM users WHERE id = $id");    }}?>


مشاكل هذا النهج واضحة:



  • الارتباط الصارم (tight coupling) - الفئة UserService مرتبطة بـ MySQLConnection. للتبديل إلى PostgreSQL، سيتعين عليك تغيير كود الفئة.
  • صعوبة الاختبار - لن تتمكن من استبدال قاعدة البيانات بكائن وهمي (mock) في اختبارات الوحدة.
  • انتهاك مبدأ المسؤولية الواحدة - الفئة لا تقوم فقط بالعمل مع المستخدمين، بل أيضًا بإنشاء اتصال بقاعدة البيانات.


الآن دعنا نعيد كتابة هذه الفئة باستخدام حقن التبعية:



<?phpinterface DatabaseInterface {    public function query($sql);}

class MySQLConnection implements DatabaseInterface { public function query($sql) { // تطبيق لـ MySQL }}

class PostgreSQLConnection implements DatabaseInterface { public function query($sql) { // تطبيق لـ PostgreSQL }}

class UserService { private $db; // يتم حقن التبعية عبر المُنشئ public function __construct(DatabaseInterface $db) { $this->db = $db; } public function getUser($id) { return $this->db->query("SELECT * FROM users WHERE id = $id"); }}

// الاستخدام$db = new MySQLConnection('localhost', 'user', 'pass');$userService = new UserService($db);?>


الآن UserService لا يعرف مع أي قاعدة بيانات يعمل بالضبط. إنه ببساطة يستخدم الواجهة DatabaseInterface. هذا هو جوهر حقن التبعية.



ثلاثة أنواع رئيسية لحقن التبعية



في PHP، هناك ثلاث طرق رئيسية لحقن التبعيات. دعنا ننظر إلى كل منها.



1. الحقن عبر المُنشئ (Constructor Injection)



هذه هي الطريقة الأكثر شيوعًا والموصى بها. يتم تمرير التبعيات عبر معاملات المُنشئ وتخزينها في خصائص خاصة للفئة.



<?phpclass Logger {    private $writer;        public function __construct(LogWriterInterface $writer) {        $this->writer = $writer;    }        public function log($message) {        $this->writer->write($message);    }}?>


الإيجابيات: التبعيات واضحة بشكل صريح، الكائن دائمًا في حالة صالحة (جميع التبعيات إلزامية).



السلبيات: إذا كان هناك العديد من التبعيات، يمكن أن يصبح المُنشئ كبيرًا جدًا.

المدونات

توصيات الكتب