【发布时间】:2011-03-20 23:23:47
【问题描述】:
我扩展了PDOStatement 并修改了fetch() 方法以将PostgreSQL 中时间戳和数组类型的值类型转换为日期时间和本机数组。这可以按预期工作,但在 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->exec("创建表示例(id INTEGER PRIMARY KEY, name VARCHAR)"); $db->exec("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)“测试” [“额外数据”]=> 布尔(真) }【问题讨论】:
-
你能展示一些按预期工作但没有按预期工作的代码吗?如果您已覆盖
fetch,它应该始终“正确”工作。 -
更新了一个例子。
-
用
while($r = $s->fetch()) {替换foreach是否正常?另外,请记住,parent::fetch调用返回的结果很可能不是数组,它可能为空。您可能应该添加一个is_array检查或类似的东西。 -
是的,它按预期工作。我的正常代码有效,但这开始循环到无穷大。此代码只是演示行为的示例。这不是真正的代码。