سؤال

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

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

$class = __CLASS__;
return new $class();

في الفصل التجريدي ، __CLASS__ هو اسم الفصل التجريدي ، عندما أريد فعلاً استخدام الفئة المدعومة.

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

هل يوجد حل في PHP <5.3؟ debug_backtrace()?


يحرر:

لقد أجريت اختبارًا ويبدو debug_backtrace() لن يعمل! أعتقد أن هذا هو السبب في أننا نحتاج الربط الثابت المتأخر.

<?

abstract class abstractFactory {
    public function create() {
            print_r(debug_backtrace());
            $class = __CLASS__;
            return new $class();
    }
}

class concreteFactory extends abstractFactory {}

$chimborazo = concreteFactory::create();

والنتيجة:

$ php test.php
Array
(
    [0] => Array
        (
            [file] => /var/www/test.php
            [line] => 13
            [function] => create
            [class] => abstractFactory
            [type] => ::
            [args] => Array
                (
                )

        )

)

Fatal error: Cannot instantiate abstract class abstractFactory in /var/www/test.php on line 7
هل كانت مفيدة؟

المحلول 3

بمجرد أن تفعل ذلك هو تجاوز أساليب الاستئصال المختلفة ، وتمرير اسم الفصل مباشرة:

<?

abstract class abstractFactory {

    public function create($class) {
        return new $class();
    }

    public function instantiate($class) {
        return new $class();
    }

}

class concreteFactory extends abstractFactory {

    public function create() {
        parent::create(__CLASS__);
    }

    public function instantiate() {
        parent::instantiate(__CLASS__);
    }
}


$chimborazo = concreteFactory::create();
$chimborazo = concreteFactory::instantiate();

نصائح أخرى

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

سيعود عدم وجود LSB ويعضمك لاحقًا. الترقية الآن ، حتى لو كان ذلك يعني تبديل المضيفين. في الواقع ، خاصة إذا كان ذلك يعني تبديل المضيفين. 5.3 كان خارج لمدة عام الآن.

إليك ما كنت أستخدمه حتى الانتقال إلى 5.3:

if (!function_exists('get_called_class')) {

   /**
    * Implementation of get_called_class() for pre-5.3 PHP
    *
    * @return string
    */
   function get_called_class()
   {
      $bt = debug_backtrace();
      $lines = file($bt[1]['file']);
      preg_match('/([a-zA-Z0-9\_]+)::'.$bt[1]['function'].'/',
               $lines[$bt[1]['line']-1],
               $matches);
      return $matches[1];
   }
}

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top