سؤال

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

دعنا نقول أن لدينا سوبرككلاس (يسمى "سوبر") وعلم فرعي (يسمى "Sub").

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo self::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

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

أقول هذا لأنه إذا اتصلت:

Sub::get_class_name();

الإخراج هو "سوبر"، وليس "فرعية".

وإذا اتصلت:

Sub::get_title();

مرة أخرى، الإخراج هو "سوبر"، ولدي حتى عنوان $ المعلنة في الفرعية.

لذلك هذا يعني أنه عندما أدعو وظيفة ثابتة موروثة، سيكون نطاق الوظيفة الطبقة الفائقة، وليس المرء يسمى (حتى إذا قمت بطباعة Backtrace، فسيعرض أن المكالمة تم إجراؤها على Superclass !!!)، وللحصول على النطاق كدقيق فرعي يتم إجراؤه، أحتاج إلى RedeClare هذه الطريقة داخل تلك الفئة الفرعية. حسنا هذا النوع من الهزائم الغرض من توسيع الفصول، أليس كذلك؟

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

شكرا!

هل كانت مفيدة؟

المحلول

مرة أخرى، هذا غير ممكن قبل PHP 5.3.0.

التجليد الثابت المتأخر تم تقديمه في PHP 5.3.0 ويسمح لك بالضبط ما تريد عبر static الكلمة الرئيسية.

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

get_class_name() سوف لا تزال تعود Super على الرغم من أن __CLASS__ يرجع دائما الفئة الحالية يتم الإعلان عن الطريقة التي يتم تشغيلها في (نوع من مثل __FILE__ الذي يقوم دائما بإرجاع الملف الحالي بغض النظر عما إذا قمت بتضمينه أم لا).

لأنه ليس لديك أي خيار سوى إعادة إعلان الوظيفة في Sub صف دراسي.

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';

    public static function get_class_name()        
    {
        echo __CLASS__;
    }
}

نصائح أخرى

يمكنك استخدامها get_called_class() للحصول على اسم الفصل للصف الذي تتصل به، حتى لو كان ثابتا. ليس عليك أن تعلن عنه في أي مكان.

من مثال أندرو:

class Super {
    public static function get_class1_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo get_called_class();
    }

}
class Sub extends Super {    
    public static function get_class2_name()        
    {
        echo __CLASS__;
    }

}
Sub::get_title(); // Echos Sub.
Sub::get_class1_Name(); // echos super
Sub::get_class2_Name(); // echos sub

لذلك ليس عليك إعلان أي متغيرات.

لحسن الحظ، أنا أفعل شيئا بالنسبة لي، لذلك قلت، برغي، أنا أستخدم PHP5.3. ولكن حتى ذلك، لا أحب ذلك، لا بد لي من redeClare "احصل على _class _name" في كل فصل، ربما أنا تمتد مثل 10 فصول. لذلك توصلت إلى هذا الحل:

class Super {
    protected static $classname = __CLASS__;
    public static function get_classname($name)
    {
        static::$classname = $name;
    }
    public static function get_classname()
    {
        return static::$classname;
    }
}
class Sub1 extends Super { }
class Sub2 extends Super { }
class Sub3 extends Super { }

$classes = get_declared_classes();
foreach($classes as $k => $v)
{
    if (is_subclass_of($v, 'Super'))
    {
        $v::set_classname($v);
    }
}

echo Sub1::get_classname(); // Sub1
echo Sub2::get_classname(); // Sub2
echo Sub3::get_classname(); // Sub3

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

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