أساسيات لينكس

الترقية إلى PHP 8.5: التغييرات الكاسرة والميزات المُهملة والانتقال الآمن على الخادم

دليل عملي للترقية من PHP 8.4 إلى 8.5: التغييرات التي قد تكسر التطبيق، والإهمالات الواجب تنظيفها، وطريقة اكتشافها، وتبديل PHP-FPM بأمان.

تاريخ النشر
مدة القراءة
7 دقائق
الكاتب
SKYLINE Engineering

الانتقال بتطبيق من PHP 8.4 إلى PHP 8.5 خطوة صغيرة في أغلب الأحيان، لكن عبارة "في أغلب الأحيان" ليست خطة. يسرد دليل الترحيل الرسمي التغييرات غير المتوافقة مع الإصدارات السابقة والميزات المُهملة، ونختار في هذا الدليل أكثرها تأثيرًا في التطبيقات والخوادم الفعلية، ونبيّن كيف تجدها في شيفرتك، ثم نشرح تبديل خادم Debian أو Ubuntu دون توقف طويل.

إن كنت قادمًا من 8.3 أو أقدم فاعمل على كل دليل ترحيل وسيط بالترتيب (من 8.3 إلى 8.4 ثم من 8.4 إلى 8.5) بدل القفز إلى الأخير مباشرة.

التغييرات الكاسرة الأكثر احتمالًا

الإعدادات والمحرك

  • أُزيل الإعداد disable_classes لأنه كان يخلّ بافتراضات المحرك، والإعدادات التي ما زالت تضبطه لم تعد تحصل على الحماية المتوقعة منه.
  • أصبح OPcache جزءًا من الملف التنفيذي، فهو مدمج ومحمّل دائمًا، والسطر zend_extension=opcache.so يولّد الآن تحذيرًا. احذف هذه الأسطر من أي إعدادات تنقلها من إصدارات أقدم، مع بقاء opcache.enable وopcache.enable_cli فاعلين.
  • تحذيرات جديدة عند التحويل بين الأنواع: تحويل عدد عشري (أو نص يشبهه) لا يمكن تمثيله عددًا صحيحًا يولّد تحذيرًا في التحويل الصريح والضمني، وكذلك تحويل NAN. قد تبدأ الشيفرة التي تعالج أرقامًا غير موثوقة بتسجيل تحذيرات.
  • تفكيك قيم ليست مصفوفات (عدا null) باستخدام [] أو list() يولّد تحذيرًا.
  • السمات على أهداف غير صالحة: تطبيق #[\Attribute] على صنف مجرد أو enum أو واجهة أو trait أصبح خطأً عند الترجمة بدل أن يفشل لاحقًا عبر الانعكاس.
  • لم تعد class_alias() تقبل array أو callable اسمًا مستعارًا.

الامتدادات

  • PDO: وسائط المُنشئ المستخدمة مع PDO::FETCH_CLASS تتبع الآن دلالات call_user_func_array() المعتادة، فالمفاتيح النصية تعمل وسائطَ مسماة. كما تغيّرت القيم العددية للثوابت FETCH_GROUP وFETCH_UNIQUE وFETCH_CLASSTYPE وFETCH_PROPS_LATE وFETCH_SERIALIZE، وهذا يهم فقط إن كانت الشيفرة تخزّن الأرقام أو تكتبها مباشرة بدل الثوابت.
  • الجلسات: كتابة بيانات جلسة يحتوي أحد مفاتيح $_SESSION فيها على الرمز | تولّد الآن تحذيرًا بدل الفشل الصامت، وأصبحت session_start() أكثر صرامة في التحقق من مصفوفة الخيارات.
  • MySQLi: استدعاء مُنشئ mysqli مرة ثانية على كائن مُنشأ مسبقًا يرمي الآن Error.
  • Intl يتطلب ICU بالإصدار 57.1 أو أحدث، وmbstring يستخدم بيانات Unicode 17.0.
  • الدوال القياسية: تمرير العدد 0 وسيطًا للّغة في setlocale() يرمي الآن TypeError، ولم يعد ArrayObject يقبل قيم enum.
  • كثير من دوال Bzip2 وPOSIX وSockets وSNMP وTidy وغيرها أصبحت ترمي ValueError عند تمرير قيم خارج النطاق أو تحتوي على بايت صفري، بعد أن كانت تتسامح معها.

إهمالات ينبغي تنظيفها

الميزات المُهملة تعمل في 8.5 لكنها تولّد رسائل E_DEPRECATED، وإصلاحها الآن يبقي السجلات مقروءة ويهيئ الشيفرة لإصدار رئيسي لاحق. أكثرها ظهورًا في الشيفرات القديمة:

  • تنفيذ أوامر النظام بعلامة backtick (استخدم shell_exec() صراحةً، والأفضل تجنب استدعاء الصدفة أصلًا).
  • التحويلات (boolean) و(integer) و(double) و(binary).
  • عبارات case المنتهية بفاصلة منقوطة بدل النقطتين.
  • استخدام null مفتاحًا في مصفوفة أو في array_key_exists() (استخدم نصًا فارغًا).
  • زيادة النصوص غير الرقمية بالمعامل ++ (استخدم str_increment()).
  • الدالتان __sleep() و__wakeup() (إهمال مرن، والبديل __serialize() و__unserialize()).
  • استدعاءات التنظيف التي لم يعد لها أثر: curl_close() وcurl_share_close() وfinfo_close() وimagedestroy() وxml_parser_free().
  • الدالة ReflectionProperty::setAccessible() وأخواتها في الانعكاس، إذ لم يعد لها أي أثر، وهي شائعة في مجموعات الاختبار والمكتبات القديمة.
  • الأسماء المستعارة mysqli_execute() وsocket_set_timeout()، وتمرير قيم خارج النطاق من 0 إلى 255 إلى chr()، وتمرير نص ليس بايتًا واحدًا إلى ord().
  • مخطط DSN ذو البادئة uri: في PDO، بسبب مخاطر تحميل DSN من روابط بعيدة.
  • اشتقاق $_SERVER['argc'] و$_SERVER['argv'] من سلسلة الاستعلام خارج سطر الأوامر: اضبط register_argc_argv=0 واقرأ $_GET أو $_SERVER['QUERY_STRING'] بدلًا من ذلك.

كيف تجدها في شيفرتك

ابدأ بعمليات بحث سريعة، ثم دع الأدوات والاختبارات تكمل المهمة. شغّل الأوامر من جذر المشروع مع استبعاد مجلد vendor/ لفحص شيفرتك أنت:

grep -rnE '\((boolean|integer|double|binary)\)' --include='*.php' --exclude-dir=vendor .
grep -rnE '\b(curl_close|curl_share_close|finfo_close|imagedestroy|xml_parser_free|mysqli_execute|socket_set_timeout)\s*\(' --include='*.php' --exclude-dir=vendor .
grep -rn 'setAccessible(' --include='*.php' --exclude-dir=vendor .
grep -rnE 'disable_classes|opcache\.so' /etc/php/

ثم:

  • افحص الصياغة بالملف التنفيذي الجديد. الأمر php8.5 -l يترجم الملفات دون تشغيلها، ويقبل منذ PHP 8.3 عدة ملفات دفعة واحدة. يكشف أخطاء الصياغة لكنه لا يكشف ما يظهر أثناء التشغيل فقط.
    find . -path ./vendor -prune -o -name '*.php' -print0 | xargs -0 -n 200 php8.5 -l | grep -v '^No syntax errors'
  • شغّل مجموعة الاختبارات على 8.5 مع إظهار رسائل الإهمال، بضبط error_reporting = E_ALL وlog_errors = On وdisplay_errors = Off في بيئة الاختبار، ثم اقرأ السجل.
  • التحليل الساكن. أدوات مثل PHPStan تستطيع تحليل الشيفرة على أساس إصدار مستهدف (عبر المعامل phpVersion)، فتأكد أن إصدار الأداة الذي تثبته يفهم PHP 8.5.
  • الاعتماديات. الأمر composer prohibits php 8.5 (واسمه المستعار why-not) يعرض الحزم التي تمنع قيودها الانتقال إلى PHP 8.5، فحدّثها أولًا.

تبديل الإصدار على خادم Debian أو Ubuntu

ثبّت 8.5 بجانب الإصدار الحالي، واختبره، ثم انقل الحركة إليه. في Ubuntu 26.04 LTS تتوفر حزم php8.5 في أرشيف التوزيعة نفسه. أما Debian 13 فيأتي مع 8.4، ويتطلب PHP 8.5 فيه حاليًا مستودعًا خارجيًا مثل packages.sury.org، فاقرأ تعليماته الرسمية واضبط تثبيت الأولوية (pinning) قبل إضافته.

sudo apt update
sudo apt install php8.5-fpm php8.5-cli php8.5-mysql php8.5-xml php8.5-mbstring php8.5-curl php8.5-intl
# compare loaded extensions with the old version
php8.4 -m > /tmp/mods-84.txt; php8.5 -m > /tmp/mods-85.txt; diff /tmp/mods-84.txt /tmp/mods-85.txt

انقل تعديلاتك أنت فقط (إعدادات المجمّع في /etc/php/8.5/fpm/pool.d/ والملفات الصغيرة في conf.d/) لا ملف php.ini قديمًا بأكمله، ثم وجّه خادم الويب إلى المقبس الجديد:

# Nginx: in the PHP location block
fastcgi_pass unix:/run/php/php8.5-fpm.sock;
sudo nginx -t && sudo systemctl reload nginx

# Apache with PHP-FPM
sudo a2disconf php8.4-fpm
sudo a2enconf php8.5-fpm
sudo apachectl configtest && sudo systemctl reload apache2

أبقِ خدمة 8.4 FPM مثبتة وعاملة حتى تطمئن، فيصبح التراجع مجرد إعادة توجيه المقبس وإعادة التحميل. وتذكّر أن مهام cron وعمّال الطوابير تستخدم الأمر php الذي تديره حزم Debian عبر update-alternatives، فتحقق بالأمر php -v واضبطه صراحةً عند الحاجة بالأمر sudo update-alternatives --config php.

أخطاء شائعة

  • ترقية PHP قبل ترقية إطار العمل أو نظام إدارة المحتوى، فراجع الإصدارات التي يدعمها المورّد.
  • امتدادات ناقصة بعد التبديل، وتظهر عادةً في أخطاء من نوع "class not found" أو "function not found"، وأمر diff أعلاه يكشفها.
  • نسخ إعدادات OPcache المضبوطة للإصدار القديم دون تمحيص، والأفضل البدء من الإعدادات الافتراضية للحزمة ثم إعادة ما قِسته فعلًا.
  • نسيان العمليات الدائمة (الطوابير والمجدولات وsupervisor) التي تواصل تشغيل الملف التنفيذي القديم حتى يُعاد تشغيلها.

ما الذي ينبغي فعله

  • اقرأ دليل الترحيل الرسمي من 8.4 إلى 8.5 كاملًا مرة واحدة، ودوّن البنود التي تمس شيفرتك.
  • شغّل عمليات البحث وفحص الصياغة والاختبارات على 8.5 في بيئة تجريبية مع تسجيل كل رسائل الإهمال.
  • أزل قيود Composer المانعة بمساعدة composer prohibits php 8.5.
  • ثبّت 8.5 بجانب الإصدار الحالي، وبدّل مقبس FPM، وأبقِ الإصدار القديم جاهزًا للتراجع السريع.
  • بعد التبديل راقب سجلات الأخطاء بضعة أيام، ثم أزل حزم PHP القديمة.

المصادر

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

صفحة الكاتب
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship Linux Basics for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.