ما الجديد في PHP 8: كل ما تريد معرفته!

نشرت: 2021-01-06

سنتواصل مع PHP8 في 26 نوفمبر 2020 ، وبالتأكيد ، هناك الكثير من المقالات المكتوبة بخصوص الميزات القادمة في هذا الإصدار المحترم.

PHP 8

نظرًا لأنه إصدار رئيسي ، ستكون هناك تغييرات جذرية وميزات جديدة بالإضافة إلى جعل من المهم أن تكون على دراية بكل ما يتغير. سيسهل عليك التفكير في كيفية تأثير PHP8 على تطبيقاتك وما هي الإجراءات التي يجب اتخاذها لضمان إمكانية الترقية بسهولة دون وقوع حوادث.

لقد مررنا ببعض التغييرات الأكثر أهمية لمعرفة ما سنحصل عليه في إصدار PHP التالي وما يستحق النقد.

لنبدأ بالنظرة العامة!

نظرة عامة على PHP 8

كما هو مذكور أعلاه ، تقدم PHP 8 حزمة من الميزات الجديدة والتحسينات والوظائف والإهمال للغة. من بين كل هذه ، الميزة الأكثر مناقشة هي مترجم JIT. ومع ذلك ، فإن ميزات تحسين الأداء مثل JIT تستحق الأضواء ، ولكن من المتوقع أن يكون للتحسينات النحوية المزيد من التحطيم الحقيقي لممارسي PHP ، كما نقول ، "على الأقل على المدى القصير."

تاريخ من التغيير

تم اقتراح بعض التغييرات في PHP ومناقشتها وتنفيذها واعتمادها في وقت قصير. إنها شائعة وغير مثيرة للجدل ولديها طريقة طبيعية لتنفيذها.

وبعد ذلك يأتي الأشخاص الذين تمت تجربتهم ويفشلون ويعودون عدة مرات قبل أن نقبلهم بشكل نهائي. عدة مرات ، يستغرق التنفيذ وقتًا طويلاً للفرز ، وأحيانًا تكون الفكرة نفسها نصف مخبوزة ، وأحيانًا لم يستعد المجتمع نفسه للفكرة بعد - "لم يحن الوقت بعد."

الاعتمادات تقع مباشرة في فئة النوع. تم اقتراحها لأول مرة في عام 2016 لـ PHP 7.1. لكنهم واجهوا مقاومة عنيدة وخسروا تصويت القبول بهامش كبير. الآن ، تقدم سريعًا لمدة أربع سنوات ، ومقترح مشابه جدًا إذا كان نطاقًا محدودًا قليلاً تم طرحه مع معارض واحد فقط. من الواضح أنها فكرة حان وقتها بالتأكيد!

ما هي المشاكل مع الكود القديم؟

نظرًا لأن PHP 8 هو إصدار جديد ضخم ، يجب أن نتوقع ألا تكون الشفرة القديمة متوافقة. ومع ذلك ، تم بالفعل نقل غالبية التغييرات التي يمكن أن تقترح مضاعفات في الإصدارات 7.2 و 7.3 و 7.4 . دعنا نتحدث عن التغييرات الأخيرة الآن. هم:

السحر يقتبس الإرث

  • النوع الحقيقي
  • مرشح FILTER_SANITIZE_MAGIC_QUOTES
  • فك ارتباط $ this من عمليات الإغلاق غير الثابتة
  • array_key_exists () مع الكائنات
  • mb_strrpos () مع الترميز كوسيطة ثالثة
  • طرق تصدير () انعكاس
  • دالة convert_cyr_string ()
  • () مزيج ترتيب المعلمات
  • استعادة_تضمين_مسار المسار ()
  • دالة hebrevc ()
  • وظيفة () money_format
  • allow_url_include ini التوجيه
  • وظيفة ezmlm_hash ()

وظائف جديدة في PHP 8

str_contains

إذا كان هناك سلسلة تحتوي على أخرى ، فهناك طرق عديدة لمعرفة ذلك.

بشكل عام ، ستستخدم strpos (). كما تعلم ، يأخذ strpos () كومة قش بجانب الإبرة التي ترغب في البحث عنها. تقوم بإرجاع عدد صحيح يظهر الموضع الأول الذي ترى فيه الإبرة.

الآن ، نظرًا لأنه يعيد موضع سلسلة في أخرى ، لا يمكنك ببساطة التحقق مما إذا كان strpos () اكتشفه أم لا ؛ إذا كان يُرجع "0" (المراكز مفهرسة بصفر وتبدأ بـ 0 بدلاً من 1) ، فإن الشرط سيعاملها كقيمة خاطئة ، وتشير إلى عدم العثور عليها.

ماذا يعني ذلك؟

سيتعين عليك كتابة شرطي - "strpos (كومة قش $ ، إبرة $)! == خطأ." يشير False إلى أنه لا يمكنه العثور على موضع السلسلة. هذه طريقة غير شفافة وباطنية للبحث عن سلسلة في سلسلة! حسنًا ، ليس هذا محيرًا.

لتجنب ذلك ، تجلب PHP 8 str_contains (). وظيفة str_contains () هي إرجاع قيمة منطقية بسيطة توضح ما إذا كانت الإبرة موجودة في كومة القش أم لا. هذا أسهل بكثير في الكتابة ، بالإضافة إلى فهمه كشخص يحافظ على الكود ، أليس كذلك؟

 if (str_contains( 'Foo Bar Baz' , 'Foo' )) { // FOUND }

PHP 8: ميزات المحرك والتغييرات

هناك بعض الميزات الجديدة للمحرك ، والتغييرات التي لوحظت في PHP 8. الميزة الرئيسية ، بلا شك ، هي مترجم JIT الجديد.

مترجم JIT

  • إنفاذ LSP
  • أخطاء فادحة في تواقيع الطريقة غير المتوافقة
  • المورد "فئات"
  • XML-RPC موجود الآن في PECL
  • سلوك التوكيد
  • يتغير الانعكاس

من أجل الغرض الأساسي من هذه المدونة ، سنركز على مترجم JIT ، و "فئات" الموارد ، وأخيراً ، تغييرات API الانعكاسية.

مترجم Just-In-Time ( RFC )

نظرًا للتحسينات التي تم إجراؤها على السرعة قبل إصدار PHP7 ، حدثت ولادة مترجم Just-In-Time (أو JIT). يتم تقديمه إلى PHP8 لأنه لا يوجد تقريبًا المزيد من التحسينات في السرعة التي يمكن إجراؤها دون استخدام JIT. الفكرة هي أنه سيحسن أداء PHP.

يتم ترجمة كود PHP إلى أكواد بايت عند تنفيذه ، ويتم استخدام أكواد البايت هذه بشكل أكبر لتنفيذ الخطوات في البرنامج.

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

هذا يعكس تطبيقات PHP من جانب الخادم بالتأكيد يمكن أن تكون أكثر انتشارًا مع نظام JIT المدمج في PHP.

تحتاج أولاً إلى تنشيط JIT إذا كنت تريد استخدامه. في نظام الاختبار الخاص بنا (Ubuntu 20.04) ، قمنا بالفعل بتثبيت وحدة PHP opcache ، والتي قمنا بتثبيتها مع حزمة PHP8 الأساسية. لقد قمنا بالتهيئة في الملف الموجود في /etc/php/8.0/cli/conf.d/10-opcache.ini.

الآن ، أنت جاهز تمامًا لتفعيل JIT ، أليس كذلك؟  

  • قم بتمكين opcache

يمكنك تعيين تخزين الذاكرة لإعداد opcache.jit_buffer_size . سيظهر ملفك بهذا الشكل على نظامي.

  1. zend_extension = opcache.so
  2. opcache.enable_cli = 1
  3. ؛ التكوين لوحدة php opcache
  4. opcache.jit_buffer_size = 256 م

علاوة على ذلك ، استخدم الدالة opcache_get_status () للتأكد من أنها نشطة. حرك نظرك على جزء "jit" من هذه المصفوفة واحصل على معلومات بخصوص حالة JIT الحالية.


var_dump(opcache_get_status()['jit']);

إذا تم تنشيط JIT بشكل مثالي ، فيجب طباعة ذلك كما هو موضح في الأسفل.

  1. مجموعة (7) {
  2. ["ممكن"] =>
  3. منطقي (صحيح)
  4. ["تشغيل"] =>
  5. منطقي (صحيح)
  6. ["نوع"] =>
  7. انت (5)
  8. [“opt_level”] =>
  9. إنت (4)
  10. [“opt_flags”] =>
  11. انت (6)
  12. [“buffer_size”] =>
  13. دولي (268435440)
  14. ["buffer_free"] =>
  15. دولي (268432880)
  16. }

فهل كان أسرع؟ باختصار ، كنا نقول "نعم".

لقد لاحظنا أن بعض الأشخاص يقومون بإجراء اختبارات معيارية بمساعدة مجموعة ماندلبروت ، لذلك قررنا استخدام مكتبة أنشأناها منذ فترة والتي ترسم بعض الأنواع المختلفة من الفركتلات في PHP. كل ما فعلناه هو إنشاء ثلاث فركتلات وتتبع المدة التي استغرقتها باستخدام وظيفة مبضع (). تم عرض نتائج PHP 7.4.8 أدناه.

  • حرق - 84.20269203186
  • ماندلبروت - 21.552599906921
  • تريكورن - 32.685042858124

عندما قمنا بتشغيل نفس الكود على PHP8 ، كان أسرع . الأرقام تتحدث عن نفسها. .

  • حرق - 15.272277116776
  • ماندلبروت -3.7528541088104
  • تريكورن -4.4957919120789

هذه الزيادة الهائلة في السرعة مثيرة جدًا للاهتمام. الكود الذي استخدمناه هنا يخلق فركتلات كبيرة الحجم ، لكننا نتذكر عند إنشاء الكود أن معظم وقتنا قضينا في انتظار توليد الفركتلات.

هذه الإضافة مثيرة للاهتمام بالنسبة لنا لأننا دفعنا PHP إلى حدودها في بعض المناسبات (خارج تكوين الفركتلات). يمكننا أن نلاحظ أن هذا مفيد جدًا لمستقبل PHP وسيسمح باختيار اللغة لمواقف خارج لغة الموقع العادية.

لم ننظر إلى زيادة السرعة لتطبيقات مثل WordPress أو Drupal ، ولكن مما قرأناه ، هناك بالتأكيد اختلاف بسيط في هذه الأنواع من التطبيقات. في المستقبل ، سنقوم بتنفيذ معايير على هذه المنصات لمعرفة نوع الاختلاف الذي يشير إليه JIT هناك.

أنواع الاتحاد ( RFC )

منذ PHP7 ، تحديد نوع القيم المعادة وأنواع الوسيطات التي كانت ممكنة. سيسمح هذا لـ PHP بإلقاء خطأ في حال كان نوع الوسيطة التي تمررها من نوع غير مطابق للنوع المتوقع. من الأهمية بمكان التأكد من أن الوظائف تتلقى بالإضافة إلى إنتاج الأنواع المثالية من القيمة بلغة مكتوبة بشكل فضفاض مثل PHP.

في PHP8 ، أصبح من الممكن الآن تحديد أنواع مختلفة للوسيطات وقيم الإرجاع ، مقسومة على حرف الأنبوب.

لقد أوضحنا أدناه دالة قادرة على قبول قيمة عدد صحيح أو عدد صحيح.

 function addNumbers(int|float $number1, int|float $number2) : int|float { return $number1 + $number2; }

في السابق ، كانت الوظيفة المماثلة لهذا تتطلب أن يتم إنشاؤها دون أي نوع من التلميح لأن PHP يمكنها عرض النوع بصمت في حالة عدم صحة الوسيطة التي تم تمريرها. هذا يعني أنه في حالة تعيين نوع الوسيطة كعدد صحيح ، فإن PHP ستعرض أي قيم عائمة في عدد صحيح. يمكن أن يؤدي بالتأكيد إلى عدد قليل من الأخطاء الخادعة للقبض عليها في حالة عدم اختبار الوحدة.

نحن فقط نسميها مثل أي وظيفة أخرى لاستخدام الوظيفة المذكورة أعلاه

 echo addNumbers(1, 1); // prints 2 echo addNumbers(1.1, 1.1); // prints 2.2

في حال حاولنا تمرير سلسلة إلى الوظيفة المتطابقة:

 echo addNumbers('one', 'two');

سوف نتلقى خطأ فادح PHP يصرح بأننا بحاجة لتمرير إما عدد عشري أو "int" في الوظيفة.

لا يمكنك استخدام نوع الفراغ كنوع اتحاد لأنه ينص على أن الوظيفة لن ترجع شيئًا. بكلمات بسيطة ، لا يمكنك أن تصيح بأن الدالة ستعيد فراغًا أو عددًا صحيحًا ؛ سوف تتلقى خطأ فادح PHP.

في حين أن التغيير الطبيعي الذي يمكننا رؤيته هو استخدام هذه الميزة قليلاً حيث كان من الممكن في وقت سابق فقط النص على أنواع مختلفة من القيمة في التعليقات ، مما أدى إلى أن تصبح تعليقات كتلة المستند أكثر تفصيلاً من التعليمات البرمجية.

مشغل Nullsafe (RFC)

إلى جانب عامل الاندماج الصفري ، فإن القدرة على اكتشاف قيم العودة الفارغة ممكنة مباشرة من الطرق. إذا لم تكن على علم ، فإن عامل التوحيد الصفري يتيح لك الحصول على قيمة ، ولا يتعين عليك الاختبار في حالة وجود القيمة بالإضافة إلى إرجاع قيمة مختلفة في حالة كانت القيمة الأولى خالية.

لذلك ، يمكننا القيام بذلك للحصول على قيمة من - "$ _GET superglobal". وفي حالة عدم وجود هذه القيمة ، عندئذٍ "0".


1. $page = $_GET['page'] ?? 0;

2. صدى $ الصفحة؛

إن عمل عامل التشغيل الآمن null هو نفسه ولكنه يسمح لك بإنشاء اختصار مفيد واختبار العائد الفارغ بطريقة ما قبل محاولة استخدام هذه القيمة.

لاحظنا أن هذا سيكون مفيدًا في نهاية المطاف في دروبال ، حيث نميل إلى كتابة الكثير من التعليمات البرمجية للتحقق من أن "المرتجعات من الأساليب" أو "خصائص الكائن" تحتوي على أشياء قبل استخدامها. هذا أمر إلزامي بسبب الحالة السياقية للكائنات في دروبال بسبب المحتوى الذي تحتويه. سيؤدي هذا التغيير بالتأكيد إلى تبسيط بعض الشيكات.

الحجج المسماة ( RFC )

تسمح لك الوسائط المسماة بتحديد ترتيب مختلف للوسيطات ووظائف الاستدعاء. خذ الوظيفة العادية التالية التي تحتوي على معلمتين. تملأ مصفوفة بالطول المحدد.

 function fillArray(array $arrayToFill, int $number) : array { for ($i = 0 $i < $number; ++$i) { $arrayToFill[$i] =1; } return $arrayToFill; }

يمكننا تمرير الحجج في الترتيب الذي تم تعريفها ويمكن استدعاء هذه التقنية بالطريقة العادية.

 $newArray = fillArray([], 2);

اعتبارًا من PHP8 ، يمكنك الآن تسمية المعلمات أثناء تمريرها إلى الوظيفة. كما يسمح لك بإرسال المعلمات بأي ترتيب نريده.

 $newArray = fillArray(number: 2, arrayToFill: []);

مثال عادي ، لكنه يمكن أن يجعل الكود أكثر قابلية للقراءة أيضًا.

تعمل هذه التقنية مع جميع الوظائف في PHP ، وليس فقط تلك التي يحددها المستخدم. في لغة PHP ، تحتوي دوال المصفوفة والسلسلة على أوامر غير متطابقة من المعلمات. لذلك ، إنها إضافة مرحب بها حقًا.

السمات V2 ( RFC1 RFC2 RFC3 )

توفر السمات آلية لربط البيانات الوصفية بفئات PHP والوظائف وخصائص الفئة ومعلمات الوظيفة والثوابت. لا يمكن الوصول إليها مباشرة من خلال الكود ، وتحتاج إلى سحبها بمساعدة PHP المضمنة في فئات الانعكاس.

تم استخدام فئة ReflectionClass في PHP منذ PHP5 ؛ ومع ذلك ، فإن طريقة getAttribute () جديدة لـ PHP8. تقوم هذه الطريقة بإرجاع نطاق من كائنات ReflectionAttribute التي ستقوم باحتواء معلومات حول السمات.

واجهت هذه الإضافة بعض التغييرات (كما نلاحظ من طلبات التعليقات المتعددة أعلاه). في حالة إنشاء الفصل الدراسي ، يمكنك بعد ذلك استخدام ReflectionClass وطباعة معلومات السمة الموجودة على مستوى الفصل الدراسي. هناك الكثير من السمات في PHP8 ، لذلك نوصي بقراءة RFCs والتعرف على ماهيتها بالفعل وكيف يمكنك دمجها في التعليمات البرمجية الخاصة بك.

تعبير المطابقة ( RFC )

في PHP 8 ، يمكننا مقارنة تعبير المطابقة الجديد بعبارة تبديل الاختزال.

يبدو قليلاً مثل إعلان الوظيفة الذي سيعيد قيمة على أساس القيمة التي تم تمريرها.

تعتبر عبارة switch في PHP مدهشة عندما ترغب في التحقق من الشرط في التعبير المتطابق دون تضمين عبارات if متعددة تمامًا.

نقدم هنا مقارنة أساسية إذا كان آخر على تعبير متطابق.

 <?php if ($i == 'apple') { echo 'i is apple'; } elseif ($i == 'cake') { echo 'i is cake'; } else { echo 'i is pizza'; }

وهذه هي الطريقة التي ستظهر بها عبارة switch المكافئة لمثالنا السابق

 <?php switch ($i) { case 'apple': echo 'i is apple'; break; case 'cake': echo 'i is cake'; break; default: echo 'i is pizza'; }

المورد "فئات"

تأتي "فئات" الموارد في قائمة التغييرات الرئيسية في PHP 8 وتعمل كبدائل غير فورية لأنواع موارد معينة. انظر أدناه لمعرفة البدائل المتاحة تشمل:

  • تقوم الآن CurlHandle - curl_init () بإرجاع CurlHandle ، المرتبطة بمورد curl.
  • Socket / AddressInfo - يُعطى بواسطة امتداد المقابس ؛ كمية وظائف مأخذ التوصيل _ * () ترجع مأخذ توصيل ، بينما ترجع الدالة socket_address_info_lookup () مثيل AddressInfo.
  • GdImage - يمثل مورد GD ، كما تم استعادته من خلال العديد من الصور الناتجة من وظائف * ().

أيضًا ، من المهم ملاحظة أن الموارد لا يتم تدميرها بواسطة وظائف مثل curl_close (). بدلاً من ذلك ، يجب عليك إلغاء تعيين () المثيل لإزالة الإشارة إليه لأنه الآن مثيل فئة.
يمكنك الحصول على القدرة على تحديد الفئات على أنها تلميحات كتابة في وظائفك وأساليبك.
في وقت سابق ، كان علينا إرجاع القيم دون كتابة أو ترك وسيطات الموارد وتوثيقها من خلال التعليقات التوضيحية ، ولكن الآن ، يمكنك الحصول على أنواع صريحة ، وهذا لا يجعل شفرتك أكثر قابلية للقراءة فحسب ، بل تجعلها أكثر أمانًا من النوع أيضًا.
ما هي المقايضة هنا؟
ستحتاج الآن إلى تحديث التعليمات البرمجية الخاصة بك إذا كنت تريد تدمير الموارد بمساعدة unset () بدلاً من الوظائف السابقة المستخدمة لهدم الموارد. يمكن تحقيق ذلك عادة من خلال البحث والاستبدال.

تغييرات انعكاس API

طفل صغير آخر ، ولكن تغيير حيوي في PHP 8 مرتبط بـ Reflection API. أثناء استخدام نظام السمات ، يمكنك استرداد هذه السمات بسهولة من خلال Reflection API على أي فئات انعكاس.
مع إضافة الأنواع المختلطة والوحدة ، أصبحت تقنيات ReflectionParameter getClass () و isCallable () و isArray () مهملة الآن.
السيناريو هو أن استخدام getType () أفضل بكثير ، وستحصل على قائمة كاملة بالأنواع التي ترضيها معلمة معينة.

تحسينات بناء الجملة PHP 8

كما نلاحظ ، JIT يسرق العناوين ؛ توفر التحسينات النحوية في PHP 8 مزايا ضخمة لجودة الحياة لمطوري PHP.
بغض النظر عن ذلك في التخلص من النموذج المشترك بين وسيطات المُنشئ المُروَّج أو الاستثناء المُحسَّن ومعالجة الأخطاء ، فهناك الكثير الذي يشعر به المطورون بالحماس.

  • نوع زائف "مختلط"
  • أنواع الاتحاد
  • الترويج لممتلكات منشئ الفئة
  • رمي الاستثناءات من التعبيرات
  • صفات
  • :: انتشار الطبقة
  • قبض عن طريق النوع فقط
  • تطابق التعبيرات

للحفاظ على أغراض هذه المدونة ، نركز على أنواع الاتحاد والسمات وتعبيرات المطابقة.

أنواع الاتحاد

تُظهر أنواع الاتحاد أن القيمة واحدة من بين نوعين محددين أو أكثر. يتم ذلك بشريط عمودي يوضع بين كل نوع واحد مسموح به. بالنسبة للعديد من المطورين الذين يتعمقون في تعليقات PHP التوضيحية لإرجاع القيم أو تحديد المعلمات الخاصة بك ، كنت تفعل ذلك بالفعل ، على الأرجح.
يمكن أن تجلب أنواع الاتحاد الكثير من التعقيد والصعوبة في الفهم لأولئك الذين يقبلون الكثير من الأنواع المختلفة أو يعيدون الكثير من الأنواع المختلفة.
ومع ذلك ، سيكون هذا مفيدًا جدًا في عدة مناسبات. على سبيل المثال ، إذا كان بإمكانك قبول أو تنفيذ كائن للواجهة Stringable الجديدة (“string | Stringable”) ، أو سلسلة ، أو إذا كان بإمكانك قبول كائن يقوم بتنفيذ الواجهة القابلة للنقل (“المصفوفة | يمكن اجتيازها”) أو مصفوفة .

تطابق التعبيرات

تعبيرات المطابقة تقطع التخمين المتعلق بمعرفة ما إذا كان الفشل في كسر حالة تبديل معينة مقصودًا أم لا. كما أنه يبسط النمط العادي لتعيين قيمة على أساس التطابق.
عند الاستخدام ، ستتم مقارنة القيمة التي نمررها للمطابقة () مباشرة بأي تعبير موجود على الجانب الأيسر. بغض النظر عن هذا التعبير أو القيمة ، يجب أن تتطابق القيمة التي تمررها للمطابقة () حتى يتم اختيارها.
عند المطابقة ، يتم تقدير التعبير الموجود على اليمين ، ويتم إرجاع قيمته المرتجعة ، بينما يمكن أن تكون التعبيرات فقط دالة Lambda أو وظائف callables ، ولا يُسمح بإغلاق متعدد الأسطر.

صفات

يدمج PHP 8 السمات على مستوى اللغة أيضًا. في حين أن السمات موجودة لأكثر من 15 عامًا عبر تعليقات docblock التوضيحية ، فإن دمجها في اللغة يوفر أداءً أفضل وبالتأكيد المزيد من القوة والاتساق. من المحتمل أن نرى السمات يتم استخدامها بشكل كبير في تطوير الأدوات والتطبيقات السريعة.

استنتاج

بالتأكيد ، هناك بعض التغييرات في PHP8. ومع ذلك ، يبدو أن غالبية التعليمات البرمجية المهملة التي يتم حذفها مخصصة للميزات القديمة التي لم نشهد استخدامها في الآونة الأخيرة.
نحن مهتمون جدًا بملاحظة التأثير الذي سيحدثه محرك JIT على قواعد الرموز التي نستخدمها وأيضًا على مجتمع PHP الأوسع - قائلين إننا نوصي بشدة بمسح قاعدة الرموز الخاصة بك بحثًا عن عدم التوافق مع PHP8 وتشغيل اختبارات الوحدة للتأكد من أن PHP الخاص بك تعمل التطبيقات بشكل مثالي قبل أن تقول "نعم" للترقية.