هل هناك أي طريقة لاكتشاف الفئة المستهدفة بطرق ثابتة؟

StackOverflow https://stackoverflow.com/questions/83887

  •  01-07-2019
  •  | 
  •  

سؤال

يوجد أدناه مثال على التسلسل الهرمي للفصل والتعليمات البرمجية.ما أبحث عنه هو طريقة لتحديد ما إذا كان "ChildClass1" أو "ChildClass2" لديه الطريقة الثابتة التي استدعاها whoAmI() دون إعادة تنفيذها في كل فئة فرعية.

<?php

abstract class ParentClass {

    public static function whoAmI () {

        // NOT correct, always gives 'ParentClass'
        $class = __CLASS__;

        // NOT correct, always gives 'ParentClass'. 
        // Also very round-about and likely slow.
        $trace = debug_backtrace();
        $class = $trace[0]['class'];

        return $class;
    }
}

class ChildClass1 extends ParentClass {

}

class ChildClass2 extends ParentClass {

}

// Shows 'ParentClass'
// Want to show 'ChildClass1'
print ChildClass1::whoAmI(); 
print "\n";

// Shows 'ParentClass'
// Want to show 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";
هل كانت مفيدة؟

المحلول 3

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

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

لغرض تحديد الفصل كما تم طرحه في هذا السؤال، فإن get_called_class() الوظيفة مناسبة:

<?php

abstract class ParentClass {

    public static function whoAmI () {
        return get_called_class();
    }

}

class ChildClass1 extends ParentClass {

}

class ChildClass2 extends ParentClass {

}

// Shows 'ChildClass1'
print ChildClass1::whoAmI(); 
print "\n";

// Shows 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";

ال ساهم المستخدم بملاحظات لـ get_called_class() قم بتضمين بعض نماذج التطبيقات التي يجب أن تعمل في PHP 5.2 أيضًا من خلال الاستفادة من debug_backtrace().

نصائح أخرى

أعتقد أن ما تشير إليه هو خطأ PHP معروف.يهدف Php 5.3 إلى معالجة هذه المشكلة من خلال ميزة Late Static Binding الجديدة.

http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html

غالبًا ما يكون تحديد الفئة أحد أعراض تعدد الأشكال غير المفهوم جيدًا.

لا يجب على عملاء ChildClass1 وChildClass2 التمييز بينهما.

لا يوجد مكان حيث يجب على أي فصل أن يسأل عنه someObject.whoAmI().

كلما كان لديك الرغبة في الكتابة if someObject.whoAmI() == 'ChildClass1' { do X(someObject) } يجب عليك حقا إضافة X() طريقة إلى ParentClass مع تطبيقات مختلفة في ChildClasses المختلفة.

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

اعتبارًا من PHP 5.3، سيكون من الممكن استخدام الكلمة الأساسية الثابتة, ، لكن في الوقت الحالي هذا غير ممكن.

لا.انتظر PHP 5.3.

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