مستودع واحد مع PHP: تنظيم الكود للمشاريع القابلة للتوسع
في تطوير PHP الحديث، تصبح إدارة الكود أمرًا بالغ الأهمية مع نمو المشروع. غالبًا ما يؤدي النهج التقليدي المتمثل في مستودعات منفصلة متعددة (polyrepo) إلى مشاكل في المزامنة، وتكرار التبعيات، وصعوبات في إعادة الهيكلة. البديل هو المستودع الواحد (Monorepo)، حيث يتم تخزين جميع الكود، بما في ذلك المكتبات والأدوات المساعدة والتطبيقات، في مستودع Git واحد. في هذه المقالة، سنشرح كيفية تنظيم مستودع واحد في PHP باستخدام Composer وGit والأدوات الحديثة.
ما هو المستودع الواحد ولماذا هو مطلوب في PHP؟
المستودع الواحد هو مستودع واحد يحتوي على عدة مشاريع أو حزم أو وحدات قد تكون مرتبطة منطقيًا. بالنسبة لمطور PHP، هذا يعني أن نواة الإطار، وخدمة API، ولوحة الإدارة، والمكتبات المشتركة موجودة في مجلد واحد.
مزايا المستودع الواحد:
- إصدار موحد: يتم تنفيذ جميع التغييرات بشكل ذري — إصلاح في مكتبة يكون مصحوبًا فورًا بتحديث الكود الذي يستخدمها.
- تبسيط إعادة الهيكلة: يمكنك تغيير واجهة الحزمة وتحديث جميع التبعيات على الفور في إطار طلب سحب واحد (pull request).
- توحيد الأدوات: ملف
composer.jsonواحد للجذر، وقواعد موحدة للفحص lint والاختبار. - تقليل التكرار: لا يلزم نشر الكود المشترك (مثل DTO، والمساعدات) على Packagist — فهو متاح مباشرة.
ومع ذلك، يتطلب المستودع الواحد انضباطًا: بدون هيكل واضح، يتحول إلى "مزبلة". مفتاح النجاح هو التنظيم الصحيح باستخدام Composer autoload ووحدات Git الفرعية أو أدوات متخصصة مثل monorepo-builder.
هيكل المستودع الواحد في PHP
لنفكر في هيكل نموذجي لمشروع PHP حيث توجد عدة مكتبات وتطبيق واحد. يبدو الدليل الجذري كالتالي:
my-monorepo/├── packages/│ ├── core/ # المكتبة الأساسية (النواة)│ │ ├── src/│ │ │ └── CoreClass.php│ │ └── composer.json│ ├── logger/ # التسجيل│ │ ├── src/│ │ └── composer.json│ └── api/ # حزمة API (قد تكون تطبيقًا منفصلاً)│ ├── src/│ │ └── Controllers/│ └── composer.json├── apps/│ └── web/ # تطبيق الويب (Laravel/Symfony)│ ├── public/│ ├── src/│ └── composer.json├── composer.json # composer.json الجذري (حزمة وصفية)├── phpunit.xml.dist└── .gitignoreمبادئ التنظيم:
- جميع الحزم موجودة في
packages/. كل حزمة لها ملفcomposer.jsonخاص بها مع اسم فريد (مثلmycompany/core). - التطبيقات (الواجهة الأمامية، لوحة الإدارة، API) موجودة في
apps/. يمكنها استخدام الحزم منpackages/كتبعيات محلية. - يعمل ملف
composer.jsonالجذري كتهيئة عامة (autoload، نصوص برمجية).
إعداد Composer للعمل مع المستودع الواحد
لكي يعمل التحميل التلقائي PHP دون نشر الحزم على Packagist، نستخدم مستودعات المسار (path repositories). أضف الكتلة التالية إلى ملف composer.json الجذري:
{ "name": "mycompany/monorepo", "require": { "mycompany/core": "*", "mycompany/logger": "*" }, "repositories": [ { "type": "path", "url": "packages/*" } ], "autoload": { "psr-4": { "MyCompany\\\\": "packages/" } }, "scripts": { "test": "phpunit" }}الآن، عند تنفيذ composer install، سيقوم Comp