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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kenaniah at gmail dot com
New email:
PHP Version: OS:

 

 [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: Sat Nov 09 23:01:30 2024 UTC