题
下面是一个示例类层次结构和代码。我正在寻找一种方法来确定“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 bug。Php 5.3 旨在通过新的后期静态绑定功能来解决此问题。
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()
父类的方法在不同的子类中有不同的实现。
这种“运行时类型识别”几乎总是可以用适当的多态类设计来替代。
从 PHP 5.3 开始,可以使用 静态关键字, ,但目前还不可能。
不。等待 PHP 5.3。