关于php:有什么方法可以在静态方法中检测目标类吗?

关于php:有什么方法可以在静态方法中检测目标类吗?

Is there any way to detect the target class in static methods?

下面是一个示例类层次结构和代码。我正在寻找的是一种方法来确定"ChildClass1"或"ChildClass2"是否具有对其调用的静态方法 whoAmI() 而无需在每个子类中重新实现它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
?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"\
"
;

// Shows 'ParentClass'
// Want to show 'ChildClass2'
print ChildClass2::whoAmI();
print"\
"
;

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

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


既然 PHP 5.3 在野外广泛使用,我想汇总这个问题的答案,以反映最新可用的技术。

正如其他答案中提到的,PHP 5.3 通过新的 static 关键字引入了后期静态绑定。此外,还提供了一个新的 get_called_class() 函数,该函数只能在类方法(实例或静态)中使用。

为了确定这个问题中所问的类,get_called_class() 函数是合适的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
?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"\
"
;

// Shows 'ChildClass2'
print ChildClass2::whoAmI();
print"\
"
;

用户为 get_called_class() 提供的注释包括一些示例实现,这些示例实现也应该在 PHP 5.2 中使用 debug_backtrace()


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

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

没有任何地方可以让任何班级询问someObject.whoAmI()

当你有编写 if someObject.whoAmI() == 'ChildClass1' { do X(someObject) } 的冲动时,你应该真正为 ParentClass 添加一个 X() 方法,并在各种 ChildClasses 中实现各种实现。

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


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


没有。等待 PHP 5.3。


推荐阅读