简体   繁体   English

使用foreach获取时覆盖PDO的fetch()

[英]Overriding fetch() for PDO when fetching using foreach

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. 我已经扩展了PDOStatement并修改了fetch()方法,以便在PostgreSQL中将类型timestamp和数组的类型转换为DateTime和native数组。 This works as intended but I can't override the behaviour when using the statement in a foreach. 这按预期工作,但在foreach中使用语句时我无法覆盖该行为。

I have solved this by returning rows into an object implementing ArrayAccess, IteratorAggregate and Countable. 我通过将行返回到实现ArrayAccess,IteratorAggregate和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)
}

The PDOStatement class implements the built-in internals-only Traversable interface. PDOStatement类实现了内置的仅内部Traversable接口。 The iterator that it implements bypasses the public PDOStatement::fetch() method. 它实现的迭代器绕过公共PDOStatement::fetch()方法。

I use something like this: 我使用这样的东西:

$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$sql = 'select * from table';
$stmt = $db->prepare($sql);
$stmt->execute();

while($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT))
{
    // do stuff
}

So the only thing you have to do is set some options :) 所以你唯一要做的就是设置一些选项:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM