I have extended PDOStatement
and modified the fetch()
method to typecast values of the types timestamp and arrays, in PostgreSQL, to DateTime and native array. This works as intended but I can't override the behaviour when using the statement in a foreach.
I have solved this by returning rows into an object implementing ArrayAccess, IteratorAggregate and Countable. However I'm not satisfied with that solution and just want a pure array back.
Example:
class ExtendedStatement extends PDOStatement { protected function __construct() { $this->setFetchMode(PDO::FETCH_ASSOC); } public function fetch( $fetch_style = PDO::FETCH_ASSOC, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0) { $r = parent::fetch($fetch_style, $cursor_orientation, $cursor_offset); if (is_array($r)) { $r["extradata"] = TRUE; } return $r; } } $db = new PDO("sqlite::memory:"); $db->setAttribute( PDO::ATTR_STATEMENT_CLASS, array("ExtendedStatement", array($db))); $db->exec("CREATE TABLE example(id INTEGER PRIMARY KEY, name VARCHAR)"); $db->exec("INSERT INTO example(name) VALUES('test')"); // This is what is does $s = $db->prepare("SELECT * FROM example"); $s->execute(); foreach ($s as $r) { var_dump($r); } $s->closeCursor(); // This is how I want it to be $s = $db->prepare("SELECT * FROM example"); $s->execute(); while ($r = $s->fetch()) { var_dump($r); } $s->closeCursor(); // This is how I want it to be $s = $db->prepare("SELECT * FROM example"); $s->execute(); var_dump($s->fetch()); $s->closeCursor();
Output:
array(2) { ["id"]=> string(1) "1" ["name"]=> string(4) "test" } array(3) { ["id"]=> string(1) "1" ["name"]=> string(4) "test" ["extradata"]=> bool(true) } array(3) { ["id"]=> string(1) "1" ["name"]=> string(4) "test" ["extradata"]=> bool(true) }