1

下面是一个示例类层次结构和代码。我正在寻找的是一种方法来确定“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";
4

5 回答 5

7

我相信你指的是一个已知的 php 错误。Php 5.3 旨在通过新的后期静态绑定功能解决此问题。

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

于 2008-09-17T14:36:30.890 回答
2

类识别通常是多态性没有被很好理解的症状。

ChildClass1 和 ChildClass2 的客户端不需要区分它们。

没有任何班级应该询问的地方someObject.whoAmI()

每当你有写作的冲动时,if someObject.whoAmI() == 'ChildClass1' { do X(someObject) }你真的应该X()在各种 ChildClass 中使用各种实现向 ParentClass 添加一个方法。

这种“运行时类型识别”几乎总是可以用适当的多态类设计来代替。

于 2008-09-21T00:39:08.317 回答
2

既然 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().

于 2009-09-06T04:16:26.233 回答
1

从 PHP 5.3 开始,可以使用static 关键字,但现在还不行。

于 2008-11-10T15:03:16.327 回答
0

不,等待 PHP 5.3。

于 2008-09-17T14:45:52.270 回答