[英]Fetch parent class data from static method
在现有的代码库中,我有一个静态生成器方法,该方法返回一个实例。 这是一个简化的示例:
class Grandparent{
}
class Parent extends Grandparent{
}
class Child extends Parent{
public static fetchChildById($id){
// ...
return new Child;
}
}
在实际代码中,我只有一个Grandparent
类和几个类似于Parent
and Child
子类(而不仅仅是Parent
和Child
)。
我现在需要在Grandparent
处实现一个新方法,以在fetchChildById()
。 这种方法需要利用同一父级的所有子级共有的某些数据。 由于我还没有一个类实例,所以我被迫将所有内容都设为静态,但是由于无法覆盖静态属性和方法,因此当然不能正常工作:
class Grandparent{
protected static $data = array(
'default',
);
protected static function filter(){
foreach(self::$data as $i){ // <!-- Will always be `default'
// ...
}
}
}
class Parent extends Grandparent{
protected static $data = array(
'one',
'two',
);
}
class Child extends Parent{
public static fetchChildById($id){
self::filter();
// ...
return new Child;
}
}
我认为这是后期静态绑定的用例, 但是代码需要在PHP / 5.2.0上运行:(
我不喜欢我想到的显而易见的解决方法:
创建一个单独的构建器类建议更多的反省,这是我目前无法承受的:
$builder = new ChildBuilder; $bart = $builder->fetchChildById(1);
创建其他实例看起来很丑陋(同时也意味着许多更改):
$builder = new Child; $bart = $builder->fetchChildById(1);
全局变量...哦,我还没那么迫切。
我是否忽略了一些自定义$data
明显机制?
这是使用反射的替代方法。 它将需要修改所有fetchChildById
实现,但这对于通过全局查找/替换来完成是很简单的:
self::filter(__CLASS__); // this is the modification
然后filter
将变为:
protected static function filter($className){
$reflect = new ReflectionClass($className);
$data = $reflect->getStaticPropertyValue('data');
foreach($data as $i){
// ...
}
}
更新: $data
属性必须是公共的,以上内容才能起作用(抱歉,我在探索中写了public
)。 但是有一个等效版本没有此要求:
$reflect = new ReflectionProperty($className, 'data');
$reflect->setAccessible(true);
$data = $reflect->getValue();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.