簡體   English   中英

從靜態方法獲取父類數據

[英]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子類(而不僅僅是ParentChild )。

我現在需要在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM