有什么方法可以在静态方法中检测目标类?
下面是示例类层次结构和代码。我正在寻找一种确定'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";
解决方案
回答
我相信我们指的是已知的PHP错误。 Php 5.3旨在通过新的Late Static Binding功能解决此问题。
http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html
回答
否。等待PHP 5.3.
回答
类标识通常是未充分理解的多态性的症状。
ChildClass1和ChildClass2的客户端不需要区分它们。
没有地方可以让任何类都问someObject.whoAmI()
。
每当我们有写if someObject.whoAmI()=='ChildClass1'{do X(someObject)}
的冲动时,我们实际上应该向ParentClass添加X()
方法,并在各种ChildClasses中进行各种实现。
这种"运行时类型标识"几乎总是可以用适当的多态类设计来代替。
回答
从PHP 5.3开始,可以通过使用static关键字来实现,但目前尚不可能。
回答
既然PHP 5.3可以在野外广泛使用,我想对这个问题汇总一下答案,以反映最新可用的技术。
如其他答案中所述,PHP 5.3通过新的static
关键字引入了Late Static Binding。同样,还提供了一个新的get_drawn_class()
函数,该函数只能在类方法(实例或者静态)中使用。
为了确定该问题所要求的类,get_drawn_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()提供的注释包括一些示例实现,这些示例实现也可以通过使用`debug_backtrace()在PHP 5.2中工作。