ترحيل مواقع PHP القديمة دون تعطيل العمليات التجارية
تعلم كيفية الانتقال من PHP القديمة إلى الأنظمة الحديثة دون توقف أو فقدان بيانات، مع استراتيجيات للتشغيل المتوازي، أعلام الميزات، وخطط التراجع.

في DigiForge، شهدنا العديد من مشاريع ترحيل PHP القديمة التي تنحرف عن المسار — ليس لأن التكنولوجيا صعبة، بل لأن العمل استمر في العمل أثناء النقل. كلمة "ترحيل" نفسها تأتي من اللاتينية بمعنى الانتقال من مكان إلى آخر، وفي الحوسبة تعني تحديدًا "البدء في استخدام نظام حاسوبي جديد، أو نقل المعلومات من نوع نظام إلى آخر" [1]. يبدو ذلك بسيطًا، ولكن عندما تقوم بترحيل تطبيق PHP متجانس يعالج الطلبات وجلسات المستخدمين وتكاملات الدفع، فإن التحدي الحقيقي هو ضمان ألا يلاحظ عملاؤك أي شيء.
قيّم قبل أن تلمس سطرًا من الكود
قبل أن نفكر حتى في كتابة موجهات جديدة أو تثبيت إطار عمل حديث، نقوم بتدقيق التطبيق الحالي — ليس فقط كوده، بل سلوكه أثناء التشغيل. ابدأ بجرد شامل لجميع نقاط الدخول: كل مسار، كل مهمة مجدولة، كل مهمة في قائمة الانتظار. غالبًا ما تحتوي تطبيقات PHP القديمة على نقاط نهاية مخفية — ربما ملف cron.php يقوم بتشغيل الرواتب كل يوم أحد، أو نقطة نهاية API مخصصة تستخدمها خدمة شحن تابعة لجهة خارجية. إذا فاتتك واحدة، فسوف يكسر الترحيل شيئًا ما.
نصيحة احترافية من مشاريع DigiForge: قم بإعداد وكيل عكسي يسجل كل طلب لمدة أسبوع كامل قبل أن تلمس بيئة الإنتاج. هذا يلتقط حركة المرور التي لم تكن تعلم بوجودها — بما في ذلك البوتات والمراقبين الداخليين وتلك التكاملات التي نسي المطور السابق توثيقها.
أثناء التدقيق، قم أيضًا بتوثيق تدفق البيانات: كيف يتصل التطبيق القديم بقاعدة البيانات؟ هل هناك إجراءات مخزنة؟ هل يوجد نظام ملفات مشترك للصور المرفوعة أو ملفات الجلسة؟ تعتمد العديد من تطبيقات PHP القديمة على جلسات قائمة على الملفات، والتي لا تتوسع أفقيًا. هذه علامة تحذيرية نتعامل معها مبكرًا، غالبًا عن طريق ترحيل الجلسات إلى Redis أو قاعدة بيانات.
اختر استراتيجية ترحيل تتوافق مع درجة تحملك للمخاطر
في DigiForge، نوصي عادةً بإحدى ثلاث استراتيجيات، اعتمادًا على مقدار المخاطرة التي يمكن للشركة تحملها.
إعادة الكتابة الشاملة (Big Bang Rewrite)
هذه هي الطريقة الأكثر دراماتيكية: تقوم ببناء النظام الجديد من الصفر، ثم تتحول إليه دفعة واحدة. وهي أيضًا الأكثر خطورة. لقد رأيناها تنجح فقط عندما يكون التطبيق القديم صغيرًا (بضع عشرات من الصفحات) أو عندما يمكن للشركة تحمل نافذة صيانة مخططة. بالنسبة لأي شيء يتضمن معاملات فورية أو عملاء على مدار الساعة، تجنب هذا النهج.
نمط شجرة التين الخانق (Strangler Fig Pattern)
سُمي هذا النمط على اسم النبات الاستوائي الذي يلتف حول مضيفه ببطء، ويتيح لك استبدال أجزاء من التطبيق القديم تدريجيًا. يمكنك توجيه مسارات URL محددة أو نقاط نهاية API إلى الكود الجديد بينما يعمل الباقي على PHP القديم. يمكن لموازن التحميل أو الخادم الوكيل العكسي (مثل Nginx أو HAProxy) توجيه حركة المرور بناءً على مسار الطلب. كل جزء تستبدله يقلل المخاطر لأنك تغير مساحة سطح صغيرة في كل مرة. نستخدم هذا النمط في كل عملية ترحيل كبيرة تقريبًا.
أعلام الميزات في كل مكان
حتى مع نمط التين الخانق، توفر أعلام الميزات مفتاح إيقاف طارئ. إذا أرجعت نقطة نهاية الدفع الجديدة أخطاءً، تقوم بتبديل العلم وتعود حركة المرور إلى الكود القديم — كل ذلك دون نشر. تعمل أدوات مثل LaunchDarkly أو مفتاح بسيط يعتمد على قاعدة البيانات بشكل جيد. نضع كل شيء خلف علم، حتى اتصال قاعدة البيانات. بهذه الطريقة، يمكننا اختبار استعلام جديد في الإنتاج مع عدد قليل من المستخدمين فقط قبل نشره للجميع.
تنفيذ الترحيل بدون توقف
عدم التوقف لا يعني عدم وجود مخاطر — بل يعني أن المستخدم لا يرى صفحة خطأ أبدًا. المفتاح هو الكتابة المزدوجة: عند الانتقال إلى مخطط قاعدة بيانات جديد أو خلفية تخزين مختلفة، اكتب البيانات إلى النظامين القديم والجديد في وقت واحد. ابدأ بالكتابة على كليهما، والقراءة من القديم. بمجرد أن يلحق النظام الجديد بالركب وتتحقق من سلامة البيانات، قم بتبديل القراءات إلى النظام الجديد. أخيرًا، توقف عن الكتابة إلى النظام القديم. يعمل هذا مع قواعد البيانات وقوائم الانتظار وتخزين الملفات وحتى تكاملات API.
<?php
// Example: dual-write to old and new databases
$legacyDb = getLegacyConnection();
$newDb = getNewConnection();
function saveOrder($orderData) {
global $legacyDb, $newDb;
// Write to both
$legacyDb->insert('orders', $orderData);
$newDb->insert('orders', $orderData);
}
// Read from legacy until we verify new data
function getOrder($orderId) {
global $legacyDb;
return $legacyDb->fetchOne('SELECT * FROM orders WHERE id = ?', [$orderId]);
}
خلال مرحلة الكتابة المزدوجة، تقوم بتشغيل نصوص التحقق من التطابق كل بضع دقائق لمقارنة المخزنين. يتم اكتشاف أي تباين بسرعة. بمجرد أن يتطابق النظام الجديد لدورة عمل كاملة (عادة 48 ساعة)، تقوم بتحويل القراءات. راقب سجلات الأخطاء عن كثب خلال الساعة التالية — إذا ظهر أي شيء غير طبيعي، قم بالعودة فورًا.
التعامل مع حالة الجلسة
غالبًا ما يستخدم PHP القديم $_SESSION المخزنة في ملفات. بينما يتوقع تطبيق Laravel أو Symfony الجديد استخدام قواعد البيانات أو Redis للجلسات. للحفاظ على تسجيل دخول المستخدمين أثناء الترحيل، نقوم بتنفيذ جسر جلسات: يكتب التطبيق القديم الجلسات في كل من الملفات ومخزن Redis مشترك؛ بينما يقرأ التطبيق الجديد من Redis. بمجرد اكتمال الترحيل، تقوم بإيقاف تشغيل كاتب الملفات وإزالة معالج الجلسة القديم.
التحقق بعد الترحيل والتخطيط للعودة
حتى مع التخطيط الدقيق، سيحدث خطأ ما. هذه ليست تشاؤمية — بل واقعية هندسية. قبل أن تضغط على المفتاح النهائي، اكتب خطة تراجع تتضمن استعادة سجلات DNS، وإرجاع تغييرات مخطط قاعدة البيانات، وتشغيل التطبيق القديم من لقطة. تدرب على التراجع في بيئة الاختبار مرة واحدة على الأقل.
في DigiForge، نحافظ دائمًا على تشغيل بيئة الإنتاج القديمة لمدة أسبوعين على الأقل بعد أي ترحيل رئيسي. تكلفة بضعة خوادم إضافية تافهة مقارنة بتكلفة تراجع فاشل يستغرق ساعات.
يتجاوز التحقق مجرد التأكد من تحميل الصفحات. نقوم بتشغيل اختبارات المعاملات التجارية الآلية: تقديم طلب، تحديث ملف شخصي، معالجة استرداد. قارن مخرجات نقاط النهاية الحيوية لواجهة برمجة التطبيقات بين القديم والجديد. إذا كنت تستخدم أداة مراقبة مثل New Relic أو Sentry، فأنشئ تنبيهات مخصصة لأي أخطاء 5xx أو استعلامات بطيئة. أخيرًا، أشرك فريق الأعمال — اجعلهم يشغلون سير عملهم اليومي على النظام الجديد في بيئة اختبار قبل الانتقال إلى الإنتاج.
المزالق الشائعة وكيف نتجنبها
- افتراض أن الكود القديم صحيح. غالبًا ما تحتوي PHP القديمة على أخطاء صامتة أصبحت 'ميزات'. هل نكرر كل سلوك؟ أحيانًا يكون من الأكثر أمانًا إصلاح الخطأ في الإصدار الجديد إذا وافق فريق الأعمال.
- نسيان مهام cron والمهام المجدولة. استدعاءات
curlالقديمة لسكريبت مخصص؟ تحتاج إلى مكان في النظام الجديد. نقوم بترحيل مهام cron إلى مجدول مهام مثل جدولة Laravel أو عامل مخصص. - إهمال التكاملات مع الأطراف الثالثة. بوابات الدفع، واجهات برمجة تطبيقات الشحن، وخطافات الويب للشركاء ترسل البيانات بتنسيقات محددة. اختبر نقاط نهاية التكامل مبكرًا — لا تريد اكتشاف عدم تطابق في التنسيق يوم الجمعة الأسود.
درس آخر تعلمناه: لا تثق في الوثائق القديمة. الكود هو مصدر الحقيقة. نقوم دائمًا بتحليل عميق للكود مع المطور الذي كتبه في الأصل (إن أمكن) أو مع أحد أعضاء الفريق الذي حافظ عليه لسنوات. نموذجهم الذهني لغرائب التطبيق لا يُقدر بثمن.
الخاتمة
ترحيل موقع PHP قديم يشبه إجراء جراحة قلب مفتوح لمريض يركض ماراثونًا. المخاطرة حقيقية، لكن المكافأة — أداء حديث، أمان، وإنتاجية مطورين — ضخمة. في DigiForge، أرشدنا العشرات من الشركات خلال هذه العملية. المفتاح هو التحرك بخطوات صغيرة قابلة للعكس، وإبقاء النظام القديم قيد التشغيل دائمًا، وعدم التوقف عن المراقبة حتى تتأكد من استقرار النظام الجديد.
تذكر: الترحيل لا يتعلق فقط بالتكنولوجيا — بل يتعلق بالحفاظ على استمرارية عملك أثناء تغيير المحرك في منتصف الرحلة. خطط بعناية، واختبر بلا كلل، واجعل دائمًا خطة للتراجع جاهزة. لن يلاحظ مستخدموك أي تغيير.


