PHP 8.5 في تطبيقات Laravel: ما يستحق مكانًا في الكود وما تفحصه أولًا
إذا كان مشروعك على Laravel وتفكّر في الانتقال إلى PHP 8.5 الصادر في 20 نوفمبر 2025، فإعلان الإصدار لن يقول لك ما الذي يستحق أن يدخل كودك. هذا الفرز هو موضوع المقال: ما يغيّر كتابة كود التطبيق فعلًا، وما يقدّمه Laravel أصلًا بأداة جاهزة، وما يجب أن تبحث عنه في مشروعك قبل الترقية.
الاستنساخ مع التعديل وكائنات القيمة
أبدأ بالميزة الأقرب إلى قاعدة يفرضها هذا الموقع على كوده: كائنات القيمة بدل المصفوفات المفتوحة. الصنف المعرّف للقراءة فقط هو المكان الصحيح لقيمة تعبر بين طبقات التطبيق، لكن كل دالة تعيد نسخة معدّلة منه كانت قبل 8.5 تعني نسخ كل خاصية يدويًا إلى كائن جديد، أو المرور عبر get_object_vars(). الآن تقبل clone مصفوفة بالخصائص التي تريد تغييرها، فتصير دالة مثل تغيير الشفافية في صنف لون سطرًا واحدًا، ولا تحتاج إلى تحديث حين تضيف خاصية جديدة للصنف.
عامل الأنبوب: مفيد، لكن ليس دائمًا
العامل |> يمرّر قيمة عبر سلسلة دوال من اليسار إلى اليمين بلا متغيرات وسيطة. مثال php.net يحوّل عنوانًا إلى معرّف رابط: قصّ الفراغات، ثم تحويل المسافات إلى شرطات، ثم حذف النقاط، ثم الأحرف الصغيرة. في الكتابة المتداخلة تبدأ القراءة من أعمق استدعاء، أي من آخر ما كُتب؛ في الأنبوب تأتي الخطوة الأولى أولًا.
لكن لنكن صريحين: في تطبيق Laravel ستكتب Str::slug() لهذا المثال تحديدًا، والنصوص المتسلسلة وصنف Pipeline يغطيان كثيرًا من هذه السلاسل منذ زمن. مكان الأنبوب الحقيقي هو تسلسل دوال صغيرة كتبتها أنت ولا توجد لها أداة جاهزة، كنت ستكتبها متداخلة أو موزّعة على أربعة متغيرات مؤقتة.
ثلاث إضافات صغيرة تستحق الانتباه
الدالتان array_first() وarray_last() تعيدان أول قيمة أو آخرها، أو null إذا كانت المصفوفة فارغة، فتتركّبان مع عامل ??. داخل المجموعات عندك ما يقابلهما منذ البداية، لكن كود Laravel يتعامل كثيرًا مع مصفوفات عادية: قيم الإعدادات، وJSON بعد فك ترميزه، ومدخلات الطلب.
والسمة #[\NoDiscard] تجعل PHP يحذّر حين تُتجاهل القيمة المعادة من دالة، ويعلن التحويل (void) أن التجاهل مقصود. تناسب هذه السمة كائنات النتيجة تحديدًا: الدالة التي تعيد نجاحًا أو فشلًا بدل رمي استثناء هي بالضبط الدالة التي يستدعيها أحدهم وينسى أن يفحص نتيجتها.
أما امتداد URI فمدمج ومتاح دائمًا، ويحلّل العناوين وفق RFC 3986 أو معيار WHATWG URL باستخدام مكتبتي uriparser وLexbor. استدعاء getHost() على كائن Uri يحل محل قراءة المفتاح من نتيجة parse_url()، وتحصل على محلّل يتبع معيارًا مسمّى. أي مكان تفحص فيه المضيف قبل إعادة توجيه، أو تقارن فيه رابط webhook بقائمة مسموحة، يستحق هذا التغيير.
ما تبحث عنه قبل الترقية
لا شيء هنا سبب للتأجيل، بل قائمة بحث. استخدام null مفتاحًا في مصفوفة أو في array_key_exists() صار مهمَلًا، وهذا يختبئ عادة في بحث قد يكون مفتاحه فارغًا. وكذلك التحويلات غير القياسية مثل (integer) و(boolean) و(double) و(binary)، وعامل علامات الاقتباس المائلة، وجملة case المنتهية بفاصلة منقوطة. والدالتان __sleep() و__wakeup() مهمَلتان إهمالًا لينًا لصالح __serialize() و__unserialize(): افحص أصنافك التي تُسلسَل في حمولات الطوابير أو في التخزين المؤقت. وصار PHP يحذّر عند تحويل عدد عشري لا يمكن تمثيله إلى عدد صحيح، وعند تحويل NAN، وعند تفكيك قيمة ليست مصفوفة ولا null. وعلى الخادم، أُزيل إعداد disable_classes.
وهذا الموقع مثال على موقع معظم المشاريع: يعمل على Laravel 13.35.0، وملف composer.json فيه يطلب PHP بالقيد ^8.4.1. الإصدار 8.5 يحقق هذا القيد، لكن 8.4 يحققه أيضًا، فلا يمكن أن تدخل صياغة 8.5 الجديدة هذا الكود قبل رفع القيد.
الخطوة الأولى العملية: ابحث في مشروعك عن __sleep و__wakeup و(integer) و(boolean) وعلامات الاقتباس المائلة، ثم شغّل الاختبارات على 8.5. بعدها، أول صنف للقراءة فقط تلمسه هو المكان المناسب لتجربة الاستنساخ مع التعديل. المصدر: إعلان إصدار PHP 8.5 على php.net.
ملاحظات القراء