1st example:
$view = new Zend_View();
$view->foo[] = 42;
var_dump($view->foo);
The output is NULL.
Reason: If you note $view->foo[] PHP calls the __get() method. The result of isset($this->_vars
[$key]) is false so null is returned. The returned null is not assigned to $this->_vars
['foo'] so the "= 42" results into an assignment of 42 to a formerly null somewhere in the memory and gets lost.
2nd example:
$view = new Zend_View();
$view->foo = array(); $view->foo[] = 42;
var_dump($view->foo);
The output is array(0) {}.
Reason: $view->foo = array(); calls __set() and an empty array is assigned to $this->_vars
['foo'].
$view->foo[] calls __get() but returns a copy of $this->_vars
['foo'] because it is not returned by reference. The assingment "= 42" works on the copy and gets lost.
My suggestion for Zend_View_Abstract::__get() is:
public function &__get($key)
{
/**
* @todo exception?
*/
if ($key[0] == '_') { $null = null;
return $null;
}
if (!isset($this->_vars[$key])) { $this->_vars[$key] = null;
}
return $this->_vars[$key];
}
This is the exception-free version.
[1] This part is a bit ugly. I'd prefer to throw an exception instead.
[2] Every read access to an unassigned property creates a null-entry in $this->_vars[] but I don't think that this is a mission critical behaviour.
Btw:
Zend_View_Abstract::__isset() should be changed to use isset($this->_vars
[$key]) instead of array_key_exists($key, $this->_vars) because the normal behaviour of isset() on null values is to return false. Current behaviour:
$foo = null;
var_dump(isset($foo));
$view->foo = null;
var_dump(isset($view->foo));