|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #51308 PDO::FETCH_FUNC should also work with fetch()
Submitted: 2010-03-16 18:24 UTC Modified: 2010-11-15 20:50 UTC
Avg. Score:4.8 ± 0.4
Reproduced:7 of 7 (100.0%)
Same Version:4 (57.1%)
Same OS:4 (57.1%)
From: kenaniah at gmail dot com Assigned:
Status: Open Package: PDO related
PHP Version: 5.3.2 OS: *
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2010-03-16 18:24 UTC] kenaniah at gmail dot com
Currently, PDO::FETCH_FUNC can only be used in the PDOStatement::fetchAll() method. This fetch mode, however, is essentially useless since it can not be set using setFetchMode() or fetch(), and thus can not be used in iteration. 

Test script:
$db = new PDO(...);
$stmt = $db->execute("SELECT * FROM foobar");
$stmt->setFetchMode(PDO::FETCH_FUNC, 'var_dump');
foreach($stmt as $row):

Expected result:
PDO should set the fetch mode to FETCH_FUNC, and should call var_dump() when $stmt is iterated. Because no additional fetch modes were passed to setFetchMode(), var_dump() should receive an argument representing the row in PDO::FETCH_BOTH format. $row should be set to the return of var_dump(), and control should now be passed to the foreach codeblock.

IMHO, FETCH_FUNC should allow one to provide a callback function that allows full manipulation of the row before being passed into the iteration codeblock. For example, in an active record implementation, one would have to set the FETCH_CLASS method and suffer a very costly object instantiation. A callback function would allow me to clone an existing (and fully loaded) object, set my properties, and return it -- saving me upwards of 90% in execution costs for heavy objects.

Actual result:
Warning: PDOStatement::setFetchMode() [pdostatement.setfetchmode]: SQLSTATE[HY000]: General error: PDO::FETCH_FUNC is only allowed in PDOStatement::fetchAll()


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2010-11-13 12:41 UTC] visor at alt22 dot ru
Still reproduced for PHP 5.3.3
 [2010-11-15 01:07 UTC] jinmoku at hotmail dot com
you can use call_user_func_array :

$db = new PDO(...);
$stmt = $db->execute("SELECT * FROM foobar");
foreach($stmt as $row):
    call_user_func_array('var_dump', $row);
 [2010-11-15 20:50 UTC] kenaniah at gmail dot com

Thanks, but that doesn't solve the problem. Consider the use case in which you 
would want to transparently process database results between the database and 
PHP. By implementing FETCH_FUNC, one would be able to process the result set 
without having to modify every instance where the result is accessed. Your 
workaround requires that I modify my code every place I want to pre-process my 
results, as opposed to simply modifying the fetch mode on the driver once. As 
you could imagine, the workaround would be more of a headache than the actual 
bug in a fairly-sized codebase.
 [2014-01-14 06:07 UTC] netmosfera at email dot it
fell in the same problem, it should be supported also by fetch() and setFetchMode()

a function callback is way more flexible than the constructor solution (which works a bit weirdly also)

please fix this!
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Jun 18 09:01:27 2019 UTC