إعادة هيكلة الكود القديم (Legacy) بلغة PHP: كيف تحول الفوضى إلى نظام
كل مطور PHP يواجه عاجلاً أم آجلاً كوداً قديماً (Legacy) — مشروعاً قديماً، ضعيف التوثيق، وغالباً لا يعمل. بدلاً من إعادة كتابة كل شيء من الصفر (وهو أمر محفوف بالمخاطر ومكلف)، تتيح إعادة الهيكلة المدروسة تحسين الكود دون إيقاف العمليات التجارية. في هذه المقالة، سنشرح كيفية إعادة هيكلة مشاريع PHP القديمة بأمان، مع الحفاظ على وظائفها.
1. التقييم والتحضير: من أين نبدأ إعادة هيكلة الكود القديم
قبل لمس الكود، من الضروري فهم حالته الحالية. تخطِ هذه المرحلة — وستخاطر بتعطيل كل شيء.
- أنشئ نسخة احتياطية — تفريغ كامل لقاعدة البيانات وملفات المشروع.
- قم بالتدقيق — ابحث عن جميع نقاط الدخول، والتبعيات، و"الصناديق السوداء". استخدم
grepللبحث عن دوالincludeوrequireوevalوmysql_*. - اضبط البيئة — شغّل نسخة محلية من المشروع (Docker أو Vagrant أو XAMPP).
- أضف تسجيل الأخطاء — سيساعدك
error_logوالمراقبة في تتبع الأخطاء بعد التغييرات.
مثال على تدقيق بسيط عبر الطرفية:
# البحث عن دوال mysql القديمةgrep -rn "mysql_query\\|mysql_connect\\|mysql_fetch" /path/to/legacy/project/هام: إذا لم يكن في المشروع اختبارات — فإن إعادة الهيكلة تتحول إلى لعبة الروليت الروسية. أولاً، قم بتغطية المنطق الحرج بالاختبارات (حتى لو كانت سيناريوهات يدوية موثقة في ملف).
2. استراتيجية إعادة الهيكلة: خطوات صغيرة لتغييرات كبيرة
أفضل استراتيجية للكود القديم هي التحسين التدريجي. لا تحاول إعادة كتابة المشروع بأكمله في عطلة نهاية الأسبوع. استخدم نهج "قاعدة الكشافة": اترك الكود أنظف مما كان عليه قبل أن تلمسه.
2.1. اعزل التغييرات
يجب أن يكون كل تغيير في حده الأدنى وذرياً. مثال: إعادة تسمية متغير في ملف واحد، ثم استخراج الكود المكرر إلى دالة.
<?php// قبل إعادة الهيكلة (قديم)$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];$result = mysql_query($sql);
// بعد: على الأقل نقوم بالتنقية$id = (int)$_GET['id'];$sql = "SELECT * FROM users WHERE id = $id";$result = mysqli_query($link, $sql);?>2.2. استخدم أدوات الأتمتة
- PHPStan — تحليل ثابت، يكتشف الأخطاء دون تشغيل الكود.
- Rector — إعادة هيكلة تلقائية (PSR-12، استبدال الدوال القديمة).
- PHP CodeSniffer — التحقق من أسلوب الكود.
- PHPUnit — اختبار الوحدات.
مثال على تشغيل Rector لاستبدال mysql_* بـ mysqli_*:
vendor/bin/rector process src/ --set mysql-to-mysqli3. تقنيات محددة لإعادة هيكلة كود PHP
3.1. استبدال "كود السباغيتي" بالبرمجة كائنية التوجه (OOP)
غالباً ما يُكتب الكود القديم كملف واحد ضخم يخلط HTML و PHP. قسّم المنطق إلى كلاسات ودوال.
<?php// سيء: كود مختلط$user = getUser($_GET['id']);echo "<h1>مرحباً، " . $user['name'] . "</h1>";if ($_POST['action'] === 'save') { saveUser($_POST);}
// جيد: فصل المسؤولياتclass UserController { public function show(int $id): void { $user = $this->userRepository->find($id); $this->render('profile', ['user' => $user]); }}?>3.2. إزالة الكود "الميت"
الدوال غير المستخدمة، التعليقات، الكتل المعلقة — كل هذا يخلق ضوضاء. احذفها دون رحمة، ولكن تحقق عبر git log من عدم استخدام الكود في مكان آخر.
// البحث عن الدوال غير المستخدمة (يتطلب PHPStan)vendo