"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > لماذا لا يمكن إسناد استدعاءات الوظائف الافتراضية في PHP؟

لماذا لا يمكن إسناد استدعاءات الوظائف الافتراضية في PHP؟

تم النشر بتاريخ 2024-11-06
تصفح:911

Why Can\'t Attribute Defaults Function Calls in PHP?

لا يمكن استدعاء الوظائف في الإعدادات الافتراضية لسمات PHP

[مشكلة]

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

class Foo {
    public $path = array(
        realpath(".")
    );
}

يؤدي إلى خطأ في بناء الجملة. ومع ذلك، يعمل ما يلي بسلاسة:

$path = array(
    realpath(".")
);

السؤال الذي يطرح نفسه: لماذا لا يمكن استدعاء الوظائف في الإعدادات الافتراضية للسمات؟ هل هذا مقصود أم خلل في التنفيذ؟

[Answer]

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

تحدد قواعد المترجم تعريف متغير الفئة على النحو التالي:

class_variable_declaration:
      //...
      | T_VARIABLE '=' static_scalar //...
;

لذلك، لتعيين قيم متغيرة مثل $path، يجب أن تتم محاذاة القيمة المتوقعة مع مقياس ثابت. يشمل هذا المصفوفات ذات القيم التي تعد أيضًا كميات قياسية ثابتة:

static_scalar: /* compile-time evaluated scalars */
      //...
      | T_ARRAY '(' static_array_pair_list ')' // ...
      //...
;

إذا سمح النحو النحوي ببناء الجملة التالي، والذي يتوافق مع نموذج التعليمات البرمجية، فسيواجه البرنامج النصي خطأ "نوع ربط غير صالح":

class_variable_declaration:
      //...
      | T_VARIABLE '=' T_ARRAY '(' array_pair_list ')' // ...
;

يكشف تحليل نموذج التعليمات البرمجية المحدد عن الخطوات التالية:

zend_do_begin_class_declaration() // Adds an opcode
array_init(), zend_do_add_static_array_element() // Do not create new opcodes, add array to class properties
zend_do_declare_property() // Declares the property
zend_do_early_binding() // Consumes the last opcode and evaluates it

إذا لم يكن كود التشغيل متوقعًا (على سبيل المثال، يتعلق بالوظائف أو الأساليب)، فسيتم طرح خطأ.

السماح بالمصفوفات غير الثابتة ينشئ رمز التشغيل INIT_ARRAY، الذي يعطل zend_do_early_binding():

DECLARE_CLASS   'Foo'
SEND_VAL        '.'
DO_FCALL        'realpath'
INIT_ARRAY

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

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

بيان الافراج يتم استنساخ هذه المقالة في: 1729168219 إذا كان هناك أي انتهاك ، فيرجى الاتصال بـ [email protected] لحذفه.
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3