In an existing code base, I have a static builder method that returns an instance. Here's a simplified example:
class Grandparent{
}
class Parent extends Grandparent{
}
class Child extends Parent{
public static fetchChildById($id){
// ...
return new Child;
}
}
In real code I have a single Grandparent class and several subclasses similar to Parent and Child (not just Parent and Child).
I now need to implement a new method at Grandparent to be used at fetchChildById(). Such method needs to make use of certain piece of data that's common to all children from the same parent. Since I don't have a class instance yet I'm forced to make everything static but, of course, that won't work properly because it isn't possible to overrite static properties and methods:
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;
}
}
I believe it's a use case for late static binding but code needs to run on PHP/5.2.0 :(
I'm not very fond of the obvious workarounds I've thought about:
Creating a separate builder class suggest more refacting than I can afford at this time:
$builder = new ChildBuilder; $bart = $builder->fetchChildById(1);Creating additional instances looks ugly (and implies many changes as well):
$builder = new Child; $bart = $builder->fetchChildById(1);Global variables... Oh well, I'm not so desperate yet.
Am I overlooking some obvious mechanism to customize $data?
fetchChildByIdwill need to create an instance of the called class anyway; why not use that instance to buy virtual method calls insidefetchChildByIditself?debug_backtrace?