edit: Using the object was just a guess. It turns out that the problem is caused by links that were previously suspected.
Since we don’t yet know what $ res is and what $res->fetch() really returns, let me try to reproduce the behavior.
<?php $res = new Foo; echo_rows($res); function echo_rows(&$res) { // as provided in the question } class Foo extends ArrayObject { protected $bar, $counter; public function fetch() { if ( ++$this->counter > 4 ) { return false; } else { $this->bar['ccorID'] = $this->counter; return $this->bar; } } public function __construct() { $this->bar = new ArrayObject; $this->counter = 0; } }
prints
1 1 2 2 3 3 4 4 ---.--- 4 4 4 4 4 [{"ccorID":4},{"ccorID":4},{"ccorID":4},{"ccorID":4}]
The reason is that all the elements in $ rows point to the same base object (see http://docs.php.net/language.oop5.references ), since my Foo class always returns the same object and just changes the state of this single object.
update: "what can manual mean when it says:" Use a reference operator to copy an array by reference? "
Let's start with this script.
<?php $arr = array(); $s = ''; $b = array(); $b['foo'] = $arr; $b['bar'] = $s; $b['foo']['bar'] = 1; $b['bar'] = 'xyz'; var_dump($arr, $s);
conclusion
array(0) { } string(0) ""
i.e. $b['foo']['bar'] = 1; and $b['bar'] = 'xyz'; did not change $ arr and $ s, since the array contains copies of the values.
Now change the two assignments to use links
$b['foo'] = &$arr; $b['bar'] = &$s;
and the output changes to
array(1) { ["bar"]=> int(1) } string(3) "xyz"
i.e. items are not copies.