[英]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.