یک پروژه PHP قدیمی معمولاً فقط «کد بد» نیست؛ سالها قانون کسبوکار، استثنا و اتصال به سرویسهای مختلف در آن جمع شده است. به همین دلیل مهاجرت PHP به Laravel را نباید صرفاً تبدیل syntax دید. هدف، کاهش ریسک و هزینه تغییر است، در حالی که محصول جاری به کار ادامه میدهد.
اول دلیل مهاجرت را دقیق کنید
«قدیمی بودن» دلیل کافی نیست. مشکل ممکن است زمان انتشار، آسیبپذیری، نبود تست، دشواری استخدام یا محدودیت عملکرد باشد. برای هر مورد baseline بسازید: مدت تحویل یک feature، نرخ خطا یا نسخههای منقضی. اگر معیار نداشته باشیم، بازنویسی جدید هم ممکن است همان مشکلات را با ظاهر تازه تکرار کند.
رفتار موجود را ثبت کنید
مستندات اغلب کامل نیستند و بعضی رفتارهای عجیب عملاً بخشی از قرارداد محصول شدهاند. characterization test ورودی و خروجی فعلی را ثبت میکند، بدون اینکه ادعا کند رفتار درست است. log، queryهای production و گفتوگو با کاربران عملیاتی نیز قوانین پنهان را آشکار میکنند.
بازنویسی یکباره چرا پرریسک است؟
در ماههای بازنویسی، محصول قدیمی هنوز تغییر میکند و نسخه جدید دائماً دنبال آن میدود. روز مهاجرت، حجم زیادی از رفتار و داده یکباره عوض میشود و rollback دشوار است. همچنین تیم دیر بازخورد واقعی میگیرد.
بازنویسی طولانی، ریسک را حذف نمیکند؛ آن را تا روز انتشار پنهان میکند.
از Strangler Pattern استفاده کنید
Laravel کنار سیستم قبلی قرار میگیرد و یک مسیر محدود را تحویل میگیرد. routing در proxy یا لایه برنامه تعیین میکند هر request به کدام سیستم برود. با مهاجرت هر قابلیت، سهم سیستم جدید بیشتر میشود تا بخش قدیمی قابل خاموشکردن باشد.
برای شروع، قابلیتی با مرز روشن، ارزش واقعی و وابستگی متوسط انتخاب کنید. login مرکزی یا هسته مالی معمولاً اولین گزینه خوبی نیست، مگر اینکه مشکل اصلی دقیقاً همانجا باشد.
دیتابیس را با احتیاط جدا کنید
استفاده موقت از schema موجود میتواند ریسک را کم کند. dual write مستقیم به دو دیتابیس معمولاً دردسر ناسازگاری دارد. اگر داده باید منتقل شود، outbox، event یا job قابل retry با reconciliation طراحی کنید. هر انتقال نیاز به count، checksum یا گزارش اختلاف دارد.
migration destructive را در چند release انجام دهید: ساخت جدید، backfill، تغییر خواندن و نوشتن، سپس حذف قدیمی.
مرز ضدفساد بسازید
نامها و ساختارهای قدیمی را مستقیم در تمام کد جدید پخش نکنید. یک adapter بین مدل جدید و API یا دیتابیس قدیمی قرار دهید. این لایه ترجمه شاید در ابتدا اضافه به نظر برسد، اما روز حذف legacy ارزشش را نشان میدهد.
امنیت و عملیات را همزمان مدرن کنید
مهاجرت فرصت خوبی برای centralize کردن secret، log ساختاریافته، CI، backup و مانیتورینگ است. بااینحال همزمانکردن ده تغییر زیرساختی با اولین قابلیت، دامنه شکست را بزرگ میکند. هر مرحله باید release و rollback مستقل داشته باشد.
زمان خاموشکردن را تعریف کنید
بخش قدیمی وقتی تمام شده که ترافیک ندارد، داده آن reconcile شده، runbook و jobهایش منتقل شدهاند و dependency ناشناختهای باقی نمانده است. فقط archive کردن repository کافی نیست؛ دسترسی، سرور و secretهای قدیمی را ببندید.
یک نقشه مهاجرت واقعبینانه
- اندازهگیری مشکل و inventory قابلیتها.
- ثبت رفتار حیاتی با تست و log.
- ساخت زیرساخت Laravel و مسیر routing.
- مهاجرت یک vertical slice کامل.
- اندازهگیری، یادگیری و تکرار.
پیش از شروع، ممیزی کد و معماری کمک میکند بدانید چه چیزی باید حفظ، اصلاح یا جایگزین شود. برای برنامه مرحلهای نیز مشاوره معماری Laravel مناسب است.
پرسشهای متداول
بازنویسی کامل سریعتر نیست؟
در ظاهر شاید؛ اما رفتارهای پنهان، توقف توسعه و مهاجرت داده معمولاً زمان و ریسک بازنویسی یکباره را چند برابر میکنند.
از کدام بخش مهاجرت را شروع کنیم؟
بخشی با مرز روشن، ارزش تجاری مناسب و وابستگی کنترلشده؛ نه لزوماً پیچیدهترین هسته سیستم.