تحذير Dynamic Property في PHP 8.2: الحل في ووردبريس

مكعب زجاجي يمثل كلاس PHP وقطعة منفلتة تُعاد إلى إطاره، رمزاً لإصلاح تحذير dynamic property في ووردبريس

الاستضافة رقّت PHP لوحدها، وفجأة ملف debug.log بقى حجمه ميجابايتات من سطر واحد بيتكرر. اطمن، الموقع شغال زي ما هو. بس السطر ده بيدفن الأخطاء الحقيقية تحته، وحله أسهل مما تتخيل.

السطر المقصود يبدو هكذا:

PHP Deprecated: Creation of dynamic property My_Plugin::$settings is deprecated
in /wp-content/plugins/my-plugin/my-plugin.php on line 18

هل يكسر هذا التحذير موقعك؟

لا. كلمة Deprecated تعني أن PHP يحذّرك من سلوك سيُزال مستقبلاً، لا أنه أوقف تنفيذ الكود. الصفحات تُعرض والنماذج تعمل كما كانت قبل الترقية.

المشكلة عملية: ملف السجل يتضخم، ويصعب عليك العثور على خطأ قاتل (Fatal Error) حقيقي وسط مئات الأسطر المكررة. ولو جاء إصدار PHP يحوّل التحذير إلى خطأ، ستكون أمام موقع متوقف بدل سطر مزعج.

ما الذي يعترض عليه PHP بالضبط؟

الخاصية الديناميكية (Dynamic Property) هي خاصية تكتب فيها قيمة على كائن دون أن تكون معرّفة داخل الكلاس. انظر إلى هذا المثال:

class My_Plugin {
    public function __construct() {
        $this->settings = get_option( 'my_plugin' ); // $settings was never declared
    }
}

ظل PHP يقبل هذا بصمت لسنوات طويلة. منذ PHP 8.2 صار مهجوراً، والسبب منطقي: لو كتبت $this->setings بحرف ناقص، كان PHP ينشئ خاصية جديدة بهذا الاسم الخاطئ بدل أن ينبّهك، فتقضي ساعة تبحث عن قيمة “اختفت”.

PHP 8.2 + ووردبريس

3 طرق لإسكات تحذير Dynamic Property

  • الأفضل

    عرّف الخاصية

    سطر public $settings; داخل الكلاس. الحل الصحيح متى كان الكود ملكك.

  • سريع

    #[AllowDynamicProperties]

    للكلاسات القديمة الكبيرة التي لا وقت لإعادة كتابتها الآن.

  • مرن

    __get و __set

    حين تكون أسماء الخصائص غير معروفة مسبقاً فعلاً.

  • لا تلمسه

    كود إضافة من wordpress.org

    حدّث الإضافة أولاً، ثم أبلغ مطوّرها بسطر السجل كما هو.

ابن موقعك قطعة قطعةarabcms.com

الحل الأول: عرّف الخاصية داخل الكلاس

هذا هو الإصلاح الصحيح متى كان الكود من كتابتك، سواء إضافة (Plugin) خاصة بعميل أو ملف functions.php في القالب الفرعي (Child Theme):

class My_Plugin {
    public $settings;

    public function __construct() {
        $this->settings = get_option( 'my_plugin' );
    }
}

سطر واحد يختفي معه التحذير. وفائدة جانبية: محرر الكود مثل VS Code يفهم الكلاس الآن ويقترح عليك اسم الخاصية تلقائياً، فتقل الأخطاء الإملائية من الأساس.

الحل الثاني: السمة AllowDynamicProperties للكلاسات القديمة

أحياناً ترث مشروعاً فيه كلاس ضخم يضيف خصائص في عشرات الأماكن، ولا يسمح الوقت أو الميزانية بإعادة كتابته الآن. هنا تضيف السمة (Attribute) فوق تعريف الكلاس:

#[AllowDynamicProperties]
class Legacy_Plugin {
    // lots of old code that adds properties dynamically
}

بهذا تخبر PHP أن الكلاس يستخدم الخصائص الديناميكية عن قصد. والسطر آمن حتى لو كان العميل على إصدار أقدم من PHP 8، لأن أي سطر يبدأ بـ # يُقرأ هناك كتعليق عادي.

اعتبر هذا الحل مسكّناً مؤقتاً، وسجّل في ملاحظات المشروع أن الكلاس يحتاج إعادة هيكلة لاحقاً.

الحل الثالث: الدوال السحرية حين تكون الخصائص متغيرة فعلاً

لو كانت أسماء الخصائص غير معروفة مسبقاً، كإعدادات تأتي من قاعدة البيانات بأسماء متغيرة، خزّنها بنفسك في مصفوفة خاصة عبر الدوال السحرية (Magic Methods):

class My_Plugin {
    private $data = array();

    public function __get( $name ) {
        return $this->data[ $name ] ?? null;
    }

    public function __set( $name, $value ) {
        $this->data[ $name ] = $value;
    }
}

الكلاس الذي يعرّف __get و __set لا يطلق التحذير، لأن PHP يعتبر أنك تتحكم في التخزين بنفسك.

حالتان لا تحتاجان إصلاحاً منك

  • كائنات stdClass: يستخدمها ووردبريس بكثرة، وهي مستثناة من التحذير أصلاً.
  • كود لم تكتبه: لو كان المسار في السجل يشير إلى إضافة من wordpress.org أو قالب تجاري، لا تعدّل ملفاته؛ أي تعديل يُمسح مع التحديث التالي. حدّث الإضافة أولاً، وإن بقي التحذير افتح موضوعاً في منتدى دعمها والصق سطر السجل كما هو.

اجعل التحذيرات في السجل لا أمام الزوار

أسوأ سيناريو أن يظهر التحذير أعلى صفحة متجر عميلك أمام المشترين. اضبط wp-config.php بحيث تُكتب الرسائل في سجل الأخطاء (WP_DEBUG_LOG) ولا تُعرض:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

بعد الانتهاء من التشخيص على موقع حي، أعد WP_DEBUG إلى false حتى لا يكبر الملف بلا داعٍ.

افحص قبل أن ترقّي الاستضافة PHP

السجل لا يُظهر إلا تحذيرات الكود الذي نُفّذ فعلاً، أي الصفحات التي زارها أحد. لذلك يفضَّل أن تنسخ الموقع إلى بيئة الاختبار (Staging)، وتشغّلها على PHP 8.2 أو أحدث، ثم تمر على الصفحات المهمة: الرئيسية، المتجر، صفحة الدفع، والنماذج.

معظم الاستضافات المنتشرة في مصر والخليج تتيح تغيير إصدار PHP من لوحة التحكم مباشرة، من خيار مثل Select PHP Version في cPanel أو قسم PHP Configuration في hPanel. جرّب الإصدار الجديد على نسخة الاختبار أولاً، ولا تنتظر أن تفرضه الاستضافة على الموقع الحي.

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

الأسئلة الشائعة

س: هل أستطيع تجاهل تحذير Creation of dynamic property؟
ج: مؤقتاً نعم، فهو لا يوقف الموقع. لكنه يملأ السجل ويخفي الأخطاء المهمة، وقد يتحول إلى خطأ فعلي في إصدار PHP قادم، لذا الأفضل إصلاحه.

س: هل أعود إلى PHP 8.1 لأتخلص من التحذير؟
ج: لا يُنصح بذلك. الإصدارات القديمة تخرج من الدعم الأمني تباعاً، والحل الصحيح إصلاح الكود أو تحديث الإضافة المسببة.

س: التحذير يشير إلى إضافة مشهورة، ماذا أفعل؟
ج: حدّثها لآخر إصدار. إن استمر التحذير، أبلغ مطوّرها في منتدى الدعم بسطر السجل كاملاً، ولا تعدّل ملفاتها بنفسك.

س: هل AllowDynamicProperties حل دائم؟
ج: هو حل رسمي وآمن، لكنه يُبقي الكلاس عرضة للأخطاء الإملائية الصامتة. استخدمه للكود القديم، وعرّف الخصائص في أي كود جديد.

الخلاصة

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

مرجع المقال (بالإنجليزية): Creation of dynamic property is deprecated: fixing the most common PHP 8.2 warning in WordPress
المقال ده مش ترجمة حرفية: متكيّف للقارئ العربي ومضاف عليه سياق ووردبريس وElementor وJetEngine.

اترك تعليقاً