有什么方法可以在静态方法中检测目标类?

时间:2020-03-05 18:59:01  来源:igfitidea点击:

下面是示例类层次结构和代码。我正在寻找一种确定'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中工作。