3

我已经扩展PDOStatement并修改了fetch()将 PostgreSQL 中类型时间戳和数组的值类型转换为 DateTime 和本机数组的方法。这可以按预期工作,但是在 foreach 中使用该语句时我无法覆盖该行为。

我通过将行返回到实现 ArrayAccess、IteratorAggregate 和 Countable 的对象中解决了这个问题。但是我对该解决方案不满意,只想要一个纯数组。

例子:

类 ExtendedStatement 扩展 PDOStatement {
    受保护的函数 __construct() {
        $this->setFetchMode(PDO::FETCH_ASSOC);
    }
    公共函数获取(
        $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["额外数据"] = TRUE;
        }
        返回 $r;
    }
}
$db = new PDO("sqlite::memory:");
$db->setAttribute(
    PDO::ATTR_STATEMENT_CLASS, array("ExtendedStatement", array($db)));
$db->e​​xec("创建表示例(id INTEGER PRIMARY KEY, name VARCHAR)");
$db->e​​xec("INSERT INTO example(name) VALUES('test')");

// 这就是它的作用
$s = $db->prepare("SELECT * FROM example");
$s->执行();
foreach ($s as $r) {
    var_dump($r);
}
$s->closeCursor();

// 这就是我想要的样子
$s = $db->prepare("SELECT * FROM example");
$s->执行();
而 ($r = $s->fetch()) {
    var_dump($r);
}
$s->closeCursor();

// 这就是我想要的样子
$s = $db->prepare("SELECT * FROM example");
$s->执行();
var_dump($s->fetch());
$s->closeCursor();

输出:

数组(2){
  [“身份证”]=>
  字符串(1)“1”
  [“名称”]=>
  字符串(4)“测试”
}
数组(3){
  [“身份证”]=>
  字符串(1)“1”
  [“名称”]=>
  字符串(4)“测试”
  [“额外数据”]=>
  布尔(真)
}
数组(3){
  [“身份证”]=>
  字符串(1)“1”
  [“名称”]=>
  字符串(4)“测试”
  [“额外数据”]=>
  布尔(真)
}
4

2 回答 2

3

该类PDOStatement实现了内置的仅限内部Traversable接口。它实现的迭代器绕过了公共PDOStatement::fetch()方法。

于 2010-07-26T09:02:56.567 回答
0

我使用这样的东西:

$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
}

所以你唯一需要做的就是设置一些选项:)

于 2010-07-26T09:09:10.243 回答