Я расширил PDOStatement
и изменил метод fetch()
, чтобы привести значения типов типов timestamp и массивов в PostgreSQL к DateTime и собственному массиву.Это работает как задумано, но я не могу переопределить поведение при использовании оператора в foreach.
Я решил эту проблему, возвращая строки в объект, реализующий ArrayAccess, IteratorAggregate и Countable.Однако я не удовлетворен этим решением и просто хочу вернуть чистый массив.
Пример:
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();
Вывод:
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)
}