Well, I was completely re-coding my advanced IRC bot to allow all methods and properties to be available in $this, without the need for long chains like $this->Configuration->someProperty, etc. My code is split over several files, each containing its own class. For this to be possible, I was using __set and __get to provide access to these properties of other classes.
While doing this, I hit some trouble with one of my array’s. Upon further experimenting in a blank PHP file, I’ve determined it must be either a PHP bug or unexpected behaviour. Note, I haven’t traced the problem to __get or __set, it seems to simply be a problem with extends.
<?php
new test();
class test
{
public $oInstance;
public $aSettings = array
(
'Bot' => array(),
'Server' => array(),
'Logs' => array(),
'Extensions' => array(),
'Other' => array('Time' => '')
);
public function __construct()
{
$this->setit();
//$this->aSettings['Other']['Time'] = time();
$this->oInstance = new test2();
}
public function setit()
{
$this->aSettings['Other'] = time();
}
public function __call($sFunction, $aArgs)
{
if(method_exists($sValue, $sFunction))
{
return call_user_func_array(array($sValue, $sFunction), $aArgs);
}
}
public function __get($sName)
{
if(property_exists('test2', $sName))
{
return $this->instance->$sName;
}
}
public function __set($sName, $mValue)
{
if(property_exists('test2', $sName))
{
$this->instance->$sName = $mValue;
break;
}
}
}
class test2 extends test
{
public function __construct()
{
var_dump($this->aSettings);
}
}
?>
I stripped the $aSettings array from my actual bot code, the rest is experimental code. Anyway, everything in the code is basically the same.
As the code shows, test2 extends the test class. This means it should inherit all the public properties of test. It does inherit it fine.. the problem starts when I assign a value to $aSettings. The changes seem to take no effect at all. When $aSettings[‘Other’][‘Time’] is var_dump’d it still shows it’s original set value of ”/nothing, but the setit() method should have set the value to time(). Here’s the really weird thing: var_dump’ing $aSettings[‘Other’][‘Time’] in the setit() method shows that it has been set to time(), but any time it is var_dump’d in test2, it shows the original set value.
I really don’t know what is causing this.. but I need a fix if I’m gonna continue on with my bot. I’ve tested this on the latest PHP version (5.3.8) on Mac, Windows and Linux, all yielding the same result.
First, PHP is pretty mature and odds are if you’re doing something simple (like manipulating arrays inside a class), you probably aren’t encountering a bug, but are doing something wrong.
You must be confusing the var_dump output. The first var_dump you see in my paste below is because of the constructor of class
test2, which is instantiated in the constructor oftest. This var_dump will ALWAYS output the default value of$aSettings['Other']['Time'], because:test2does not call the parent constructor (which it can’t as that’ll be a huge memory leak since objects will be recursively created)test2created in the constructor oftestnever has any operations performed on it to change the$aSettings['Other']['Time']value (i.e. callingsetit()or setting the property through__set().test2is instantiated, it inherits the default values of the$aSettingsarray fromtest.The second is the var_dump of the object created from instantiating
test, which clearly shows that$aSettings['Other']['Time']is modified totime().See the following paste, and you’ll see that the object from class
testhas the correct value for$aSettings['Other']['Time'].http://codepad.org/lsL3mObm