Hi, Tried to post this as a comment on the wiki, but its slow/dying or dead.
One thing I think that could simplify some of this, is telling the back end where to put values, rather than ask for them and having to juggle them about. Especially when have to deal with joins and particularly self joins, as each set of fields can be bound to their own scope. The also an added advantage is that PDO & MySQLi backends can be told where to put column values, so PDOStatement::fetch(PDO::FETCH_BOUND) or MySQLI_STMT::fetch() respectively can do most of the actual mapping. A crude example (which is all kinds of wrong in other aspects... ) is below.. Jared <?php function query(PDO $pdo, $sql, array $refs = null, array $params = null) { $query = $pdo->prepare($sql); if ($query->execute($params)) { if ($refs) { $i = 1; foreach($refs as &$ref) $query->bindColumn($i++, $ref); } return function() use ($query) { return $query->fetch(\PDO::FETCH_BOUND); }; } return false; } function findAllAndBoss(PDO $pdo) { $e = array(); $b = array(); $iterator = query($pdo, 'SELECT e.id, e.name, e.email, b.id, b.name, b.email FROM "Employee" e LEFT JOIN "Employee" b ON e.boss = b.id') array( &$e['id'], &$e['name'], &$e['email'], &$b['id'], &$b['name'], &$b['email'])); return function() use (&$e, &$b, $iterator) { if ($iterator()) { // IdentityMap lookup omitted... $employee = new Employee(); $employee->setState($e); // IdentityMap lookup omitted... if (isset($b['id'])) { $boss = new Employee(); $boss->setState($b); } else $boss = null; return array($employee, $boss); } return false; }; }