There've been lots of rumors about overloaded array properties lately.
The following code
<?php
class funky {
private $p = array();
function __get($p) {
return $this->p;
}
}
$o = new funky;
$o->prop["key"] = 1;
?>
will yield:
Notice: Indirect modification of overloaded property funky::$p has no effect
As arrays are the only complex types that are passed by value (resources don't really count here) the solution to described problem is simple: use an object; either an instance of stdClass or ArrayObject will do well, depending if you want to use array index notation.
So the folloiwng code will work as expected, because the ArrayObject instance will pe passed by handle:
<?php
class smarty {
private $p;
function __construct() {
$this->p = new ArrayObject;
}
function __get($p) {
return $this->p;
}
}
$o = new smarty;
$o->prop["key"] = 1;
?>
I guess most of you already knew, but anyway... 
Explains more than one hair pulling session I have experienced over the last few months.
The __get and __set magic can be really nice, but not everything needs to be hidden behind a method, especially if all the method is doing is providing a facility that unprotected method.
(And that goes doubly so for the ArrayAccess interface -- the purpose of orienting your code around objects is to wrap complexity in a simpler interface, not to complicate existing simple idioms).