php.net |  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
Votes:9
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
 [2010-03-16 18:24 UTC] kenaniah at gmail dot com
Description:
------------
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:
---------------
<?php
$db = new PDO(...);
$stmt = $db->execute("SELECT * FROM foobar");
$stmt->setFetchMode(PDO::FETCH_FUNC, 'var_dump');
foreach($stmt as $row):
    ...
endforeach;
?>

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()

Patches

Pull Requests

History

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");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach($stmt as $row):
    call_user_func_array('var_dump', $row);
endforeach;
 [2010-11-15 20:50 UTC] kenaniah at gmail dot com
jinmoku:

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 10:01:29 2024 UTC