public final function fetchAssoc($assoc)
{
if (strpos($assoc, ',') !== FALSE) {
return $this->oldFetchAssoc($assoc);
}
$this->seek(0);
$row = $this->fetch();
if (!$row) {
return [];
// empty result set
}
$data = NULL;
$assoc = preg_split('#(\\[\\]|->|=|\\|)#', $assoc, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
// check columns
foreach ($assoc as $as) {
// offsetExists ignores NULL in PHP 5.2.1, isset() surprisingly NULL accepts
if ($as !== '[]' && $as !== '=' && $as !== '->' && $as !== '|' && !property_exists($row, $as)) {
throw new \InvalidArgumentException("Unknown column '{$as}' in associative descriptor.");
}
}
if ($as === '->') {
// must not be last
array_pop($assoc);
}
if (empty($assoc)) {
$assoc[] = '[]';
}
// make associative tree
do {
$x =& $data;
// iterative deepening
foreach ($assoc as $i => $as) {
if ($as === '[]') {
// indexed-array node
$x =& $x[];
} elseif ($as === '=') {
// "value" node
$x = $row->{$assoc[$i + 1]};
continue 2;
} elseif ($as === '->') {
// "object" node
if ($x === NULL) {
$x = clone $row;
$x =& $x->{$assoc[$i + 1]};
$x = NULL;
// prepare child node
} else {
$x =& $x->{$assoc[$i + 1]};
}
} elseif ($as !== '|') {
// associative-array node
$x =& $x[$row->{$as}];
}
}
if ($x === NULL) {
// build leaf
$x = $row;
}
} while ($row = $this->fetch());
unset($x);
return $data;
}