I finally freed up some time to finish some quick tests for some of the late static binding patches I made and one of them finally made it into head.
The original post I had bringing up this issue was lovingly title Late Static Binding...Sorta. Basically the original patch alone did not provide a means to override a method, forward execution to the parent method and still preserve the ability for static:: to be anything meaningful. It would be turned into the syntactic equivelant of self::. I came up with a few patches to address this. After several rounds of back and forth about the patches the conversation died out with no decision. I finally resurrected the topic and was able to find concensus for the third patch (forward_static_call()).
This weekend I wrapped up a few small tests and sent the patch in and it was subsequently pushed to php 5.3 and php 6.0. Now, this is not at all the way I wanted things to work, in all honesty I think the patch is pretty hokey but unfortunately nobody really spoke up in support of the changes I wanted to make to parent:: in regards to LSB. So I thought it far more important to make sure there was a way to make sure static methods could be overridden while ensuring that access to parent methods would be unabated.
So now, if you want to override a static method and forward execution to the parent class, the safe way (in regards to static inheritance) is shown in Table2 while the (unfortunately) not so safe way is shown in Table1:
<?phpclass ActiveRecord
{ public
static funtion loadById
($id, PDO
$db) { $table = get_called_class
();
$statement =
$db->
prepare("
SELECT * FROM {$table}
WHERE {$table}_id = ?
");
$statement->
execute(array($id));
$column_values = $
$statement->
fetch(PDO::
FETCH_ASSOC);
if ($column_values) { $ar =
new static($db);
$ar->
column_values =
$statement->
fetch(PDO::
FETCH_ASSOC);
return $ar;
} else { return FALSE;
} }}class Table1 extends ActiveRecord
{ public
static function loadById
($id, PDO
$db) { /**
* DANGER! the table name will resolve to ActiveRecord
*/ $ar = parent::
loadById($id,
$db);
if ($ar ===
FALSE) { return new static($db);
} }}class Table2 extends ActiveRecord
{ public
static function loadById
($id, PDO
$db) { /**
* SAFE WAY! the table name will correctly resolve to Table2
*/ $ar = forward_static_call
(array('parent',
'loadById'),
$id,
$db);
if ($ar ===
FALSE) { return new static($db);
} }}?>
This shows an example of the differences between using parent:: and forward_static_call. I really do wish that the behavior of parent:: would just be modified to work like forward_static_call does. It would be alot less awkward and imo closer to what the average oo programmer would expect. I suppose the issue is up for debate if anyone feels like bringing it up on internals, we aren't stuck with it until php 5.3 rolls
. The patch is even available it just needs some more vocal supporters.
In either case at least there is a way around it now...