Ken*_*ger 19 php oop inheritance php-5.2
我有一个抽象PHP超类,它包含需要知道其运行的子类的代码.
class Foo {
static function _get_class_name() {
return get_called_class();
//works in PHP 5.3.*, but not in PHP 5.2.*
}
static function other_code() {
//needs to know
echo self::_get_class_name();
}
}
class Bar extends Foo {
}
class FooBar extends Foo {
}
Bar::other_code(); // i need 'Bar'
FooBar::other_code(); // i need 'FooBar'
Run Code Online (Sandbox Code Playgroud)
如果我调用该函数get_called_class()
,这将有效- 但是,此代码将在PHP 5.2版中运行.*,因此该函数不可用.
那里有一些自定义的PHP实现get_called_class()
,但它们都依赖于debug_backtrack()
解析文件名和行号,并运行正则表达式(因为编码器不知道PHP 5.2有反射)来查找类名.这段代码需要能够用php运行,即.不仅来自.php文件.(它需要从php -a
shell或eval()
语句中工作.)
理想情况下,解决方案可以在不需要将任何代码添加到子类的情况下工作......我能看到的唯一可能的解决方案是将以下代码添加到每个子类中,这显然是一个恶心的黑客攻击:
class FooBar extends Foo {
static function _get_class_name() {
return 'FooBar';
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:等等,这似乎不起作用.这将是我的最后一招.任何人都可以想到类似于这个解决方案的东西,它可以让我获得所需的功能.也就是说,我愿意接受一个解决方案,它要求我为每个子类添加一个函数或变量,告诉它它的类名是什么.不幸的是,似乎self::_get_class_name()
从超类调用调用父类的实现,即使子类已经覆盖它.
小智 10
实际上,在执行超类方法时知道实际的被调用(子)类通常是有帮助的,我不同意想要解决这个问题有什么不对.
例如,我的对象需要知道类的名字,但他们做的是什么样的信息始终是相同的,可以提取到一个超类方法如果我能得到所谓的类名.甚至PHP团队也认为这很有用,可以包含在php 5.3中.
据我所知,正确和非传播的答案是,在5.3之前,你必须做一些令人发指的事情(例如回溯),或者只是在每个子类中包含重复的代码.
工作方案:
function getCalledClass(){
$arr = array();
$arrTraces = debug_backtrace();
foreach ($arrTraces as $arrTrace){
if(!array_key_exists("class", $arrTrace)) continue;
if(count($arr)==0) $arr[] = $arrTrace['class'];
else if(get_parent_class($arrTrace['class'])==end($arr)) $arr[] = $arrTrace['class'];
}
return end($arr);
}
Run Code Online (Sandbox Code Playgroud)