php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52444 Extending PDOStatement and replacing fetch() apply when using foreach
Submitted: 2010-07-26 12:57 UTC Modified: 2020-04-02 09:56 UTC
Votes:4
Avg. Score:4.8 ± 0.4
Reproduced:4 of 4 (100.0%)
Same Version:3 (75.0%)
Same OS:3 (75.0%)
From: antennen at gmail dot com Assigned:
Status: Open Package: PDO Core
PHP Version: Irrelevant OS: All
Private report: No CVE-ID: None
 [2010-07-26 12:57 UTC] antennen at gmail dot com
Description:
------------
Extending PDOStatement and replacing fetch() doesn't work when iterating using foreach. It calls the built in fetch rather than my overridden one. This can be circumvented using while($r = $s->fetch()) { .. } but I believe this behaviour is unexpected.

Test script:
---------------
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')");
$s = $db->prepare("SELECT * FROM example");
$s->execute();
foreach ($s as $r) {
	var_dump($r);
}

Expected result:
----------------
array(3) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(4) "test"
  ["extradata"]=>
  bool(true)
}

Actual result:
--------------
array(2) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(4) "test"
}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-11-26 13:31 UTC] johannes@php.net
PDO should rather implement the Iterator interface so one can override "current"
 [2014-01-01 12:48 UTC] felipe@php.net
-Package: PDO related +Package: PDO SQLite
 [2020-04-02 09:56 UTC] cmb@php.net
-Package: PDO SQLite +Package: PDO Core
 [2020-04-02 09:56 UTC] cmb@php.net
> PDO should rather implement the Iterator interface so one can
> override "current"

ACK.  And PHP 8 would likely be suitable for this change.

By the way, this is a general PDO issue, not only for PDO SQLite.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC