php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #54545 PDO::query throws exceptions with null optional arguments
Submitted: 2011-04-16 07:59 UTC Modified: 2020-10-28 15:15 UTC
Votes:6
Avg. Score:4.8 ± 0.4
Reproduced:5 of 5 (100.0%)
Same Version:1 (20.0%)
Same OS:1 (20.0%)
From: php at bucksvsbytes dot com Assigned:
Status: Wont fix Package: PDO MySQL
PHP Version: 5.3.6 OS: ubuntu
Private report: No CVE-ID: None
 [2011-04-16 07:59 UTC] php at bucksvsbytes dot com
Description:
------------
In 5.3.3 (sorry, I can't load 5.3.6 to confirm), supplying the optional fetchmode arguments (args 2,3,4) as NULL throws fatal exceptions. In 5.2, those arguments as NULL were ignored. Optional arguments supplied as NULL should always be ignored unless the NULL is significant to the logic. It looks to me like you now have to call PDO::query with exactly the right number of arguments (1, 2, 3, or 4) to avoid bombing the script.

Test script:
---------------
$db=new PDO($dsn);
unset($fetchmode,$fetch2,$fetch3);
$db->query('select * from table',$fetchmode,$fetch2,$fetch3);
//throws fatal exception
$fetchmode=0;
$db->query('select * from table',$fetchmode,$fetch2,$fetch3);
//throws different fatal exception


Expected result:
----------------
I expect query to ignore fetchmode when it is null.

Actual result:
--------------
query fails fatally

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-04-16 19:47 UTC] johannes@php.net
Which driver are you using? What's the PHP configure line? And well ... verification on 5.3.6 or svn snapshot would be great ... Please also mind that if you're using distribution packages you might issues due to their patches, which we can't verify.
 [2011-04-16 20:57 UTC] php at bucksvsbytes dot com
It doesn't appear to be a package issue to me. The error is caused by specific checking of the argument values, proved by the different exceptions below. The only problem is that a null argument should be equivalent to an omitted argument for error checking purposes. These exception appeared after switching from a 5.2 PHP server to a 5.3.

Example 1  (arg2, arg3, and arg4 of query are null):
exception 'PDOException' with message 'SQLSTATE[HY000]: General error: mode must be an integer' in /home/bvb/www/html/cl/bvc_d.php:681
Stack trace:
#0 /home/bvb/www/html/cl/bvc_d.php(681): PDO->query('select * from p...', NULL, NULL, NULL)

Example 2 (arg2 of query is 0, arg3 and arg4 are null):
exception 'PDOException' with message 'SQLSTATE[HY000]: General error: fetch mode doesn't allow any extra arguments' in /home/bvb/www/html/cl/bvc_d.php:681
Stack trace:
#0 /home/bvb/www/html/cl/bvc_d.php(681): PDO->query('select * from p...', 0, NULL, NULL)

My PDO driver is pgsql. The Configure Command display of phpinfo() is missing in 5.3, so please advise what equivalent data I should supply for the PHP configure line.
 [2011-04-17 03:14 UTC] cataphract@php.net
> The only problem is that a null argument should be equivalent to an omitted
> argument for error checking purposes

I don't know where you got this idea. An omitted argument should be equivalent to whatever initializer is specified. The documentation of PDO::query doesn't show any initializers, so you can't assume you can pass NULLs. The fact this rule is only conventional in internal functions (there's no enforced initializer functionality) doesn't make it less true; if an initializer in the docs don't match the behavior, it's a bug.

That said, it might be appropriate to have nulls have the same effect as missing arguments.
 [2011-04-17 10:31 UTC] php at bucksvsbytes dot com
Your point about initializers is absolutely correct, of course, but it seems unnecessarily cumbersome (and atypical in PHP) to require this awkward construction:
if ($a) then{
 $x=function($p1)
}elseif($b) then{
 $x=function($p1,$p2)
}elseif($c) then{
 $x=function($p1,$p2,$p3)
}
rather than simply
 $x=function($p1,$p2,$p3)
with the value of p2 and p3 determining which function logic to execute.

I leave it in your hands. Thanks for your responses.
 [2014-01-01 12:44 UTC] felipe@php.net
-Package: PDO related +Package: PDO MySQL
 [2020-08-29 14:36 UTC] cmb@php.net
> The documentation of PDO::query doesn't show any initializers, […]

That has changed in the meantime for $fetch_style.

> 'SQLSTATE[HY000]: General error: mode must be an integer'

In PHP 5 & 7, PDO doesn't type juggle the $fetch_style[1].  That
changes as of PHP 8.0.0.  The other parameters are strictly typed
in all versions.  That should be documented.

[1] <https://github.com/php/php-src/blob/php-7.4.9/ext/pdo/pdo_dbh.c#L1091>
 [2020-10-28 15:15 UTC] nikic@php.net
-Status: Open +Status: Wont fix
 [2020-10-28 15:15 UTC] nikic@php.net
Closing this as Won't Fix. In PHP 8, the signature for PDO::query() is:

    public function query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs) {}

which now gives explicit indication that the method accepts a variable number of arguments.

If you need to call query() generically, using different fetch modes, then you can also use argument unpacking to do so:

    public function myQuery(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs) {
        return $this->pdo->query($query, $fetchMode, ...$fetchModeArgs);
    }
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC