下面是一个示例类层次结构和代码。我正在寻找的方法是确定'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";
答案 0 :(得分:7)
我相信你所指的是一个已知的php bug。 Php 5.3旨在通过新的Late Static Binding功能来解决这个问题。
http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html
答案 1 :(得分:2)
类别识别通常是未被充分理解的多态性的症状。
ChildClass1和ChildClass2的客户端不应该区分它们。
任何班级都不应该问someObject.whoAmI()
。
每当你有写if someObject.whoAmI() == 'ChildClass1' { do X(someObject) }
的冲动时,你应该在ParentClass中添加一个X()
方法,并在各种ChildClasses中使用各种实现。
这种“运行时类型识别”几乎总能被适当的多态类设计所取代。
答案 2 :(得分:2)
现在PHP 5.3在野外广泛使用,我想整理一个这个问题的摘要答案,以反映新的技术。
正如其他答案所述,PHP 5.3通过新的Late Static Binding关键字引入了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";
user contributed notes for get_called_class()
包括一些应该在PHP 5.2中使用的示例实现,并使用debug_backtrace()
。
答案 3 :(得分:1)
从PHP 5.3开始,可以使用static keyword,但现在不可能。
答案 4 :(得分:0)
没有。等待PHP 5.3。