I’ve been working on a small set of classes in PHP 5.3.x that follow the Active Record pattern. I’m running to an issue, however, when working with static properties. Here’s the bit of code I’ve been testing this with:
<?php
class dbPreparedObject {
public static $insert = "";
public function __construct() {
static::$insert = "autoinsert_".get_called_class();
}
}
class gtRecord extends dbPreparedObject {}
class nRecord extends dbPreparedObject {}
$a = new gtRecord();
$b = new nRecord();
var_dump(gtRecord::$insert);
var_dump(nRecord::$insert);
Output:
string(18) "autoinsert_nRecord"
string(18) "autoinsert_nRecord"
I, however, expect the first string to read autoinsert_gtRecord.
It seems that static properties that aren’t instantiated by the child class are tied together. Is there any way to separate them without declaring public static $insert = "" in every child class?
This is the expected behavior. In PHP, properties declared static are shared amongst all instances of the object created. That is, there is only one instance of
$insertacross all instances of ofdbPreparedObjector its inherited classes.The reason you are seeing
autoinsert_nRecordfor bothvar_dumps is because that was the last object you created.Consider this minor change:
After the first var_dump, the value is
_gtRecord, but once annRecordobject is created, the static property gets changed (for all dbPreparedObject objects) to benRecordsince that was the last class.So if you plan on having multiple instances of this class,
$insertcannot be static because it will not always contain the value you expect given the code since there is only one copy of the static$insertproperty that is the same for all objects. Once you change it in one object, you change it in all objects.So we need to ask why
$insertneeds to be static or what other options to you have so you don’t run into this issue.