繁体   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