I'm with you on references. Here's what I'm finding out (assuming I understand references correctly):
A global inside a function is treated as a reference. So, if I say:
global $Cmd;
$Cmd = & new SomeClass();
there are two things of interest here. First is that the $Cmd inside the function is a reference 'pointing to' (in a symbol table sense) the real global $Cmd. I think it's best not to think of the $Cmd inside the function as the 'real' $Cmd, but rather as a local variable that is a reference to the real $Cmd. When I do the assignment, what I'm doing is setting the 'local' $Cmd to be a reference to the new object. The 'real' $Cmd isn't set to refer to that new object. It's as if I had something like this (ignoring for this example the fact that I would have to use a 'global' statement to get access to the global from within the function):
$Cmd = NULL;
function a()
{
$localRef = &$Cmd; // $localRef is a ref to the global $Cmd
$localRef = 0; // this would set $Cmd to 0
$localRef =& new SomeClass();
// note that after the line above, $localRef no longer refers to
// $Cmd, but now refers to another object.
// The last statement doesn't assign anything to $Cmd
// (which $localRef was 'pointing to'). Rather, it redefines
// $localRef to now be a reference to a new object.
}
That's why the 'real' $Cmd isn't changed.
Another way that might help to think about references is to realize that an 'assignment' of references isn't really doing an assignment. That is:
$ref = 0; // a 'real' variable with a value of 0
$ref = & $someOtherVar; // not a 'real' assignment
It helps for me to think of the second assignment as not an assignment at all. It does not assign a reference-to-$someOtherVar into $ref. Rather, it tells the symbol table manager that $ref is now a synonym for $someOtherVar. The data that used to be associated with $ref is thrown away.
Does this help, or have I made more of a hash of it?
In any case, here's what I had to do:
function Cmd()
{
global $CmdObj;
parent::Element();
if (count($CmdObj) > 0)
ReportParseError("More than one command found");
// We would like to say something simple, such as:
// $CmdObj = &$this;
// but that doesn't work. $CmdObj is a global, so in this
// function it's really a reference. We haven't really changed
// $CmdObj to 'point to' this object.
//
// Next on the simplicity scale would be something like:
// array_push($CmdObj, &$this);
//
// but array_push doesn't take a reference as a second arg.
//
// So, we push an array (containing a ref to ourselves) onto the
// $CmdObj array.
array_push($CmdObj, array(&$this));
}
I hope this helps.