php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #41622 no binding with prepare/execute
Submitted: 2007-06-07 09:53 UTC Modified: 2007-06-08 12:11 UTC
From: andrea dot spacca at gmail dot com Assigned:
Status: Closed Package: PDO related
PHP Version: 5.2.3 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: andrea dot spacca at gmail dot com
New email:
PHP Version: OS:

 

 [2007-06-07 09:53 UTC] andrea dot spacca at gmail dot com
Description:
------------
Binding params to placeholders in prepared query don't work
(i tested the script both cli and in apache enviroment)

[pdo_mysql]
PDO Driver for MySQL, client library version => 5.0.34

[pdo_sqlite]
PDO Driver for SQLite 3.x => enabled
PECL Module version => 1.0.1
SQLite Library => 3.3.17

Reproduce code:
---------------
    try {
        $sql = 'SELECT field FROM table WHERE field = :placeholder LIMIT 0, 1';

        $db = new PDO([...]);
        $tmp = $db->prepare($sql);
        $tmp->execute(array(':placeholder' => 1));

        var_dump($tmp->queryString);
        var_dump($tmp->fetchAll());

        $db = NULL;
    } catch (Exception $e) {
        var_dump($e);
    }


Expected result:
----------------
$tmp->queryString should contain the :placeholder binded to the value passed in execute(), and (as far as the query will produce row result from the db) $tmp->fetchAll() should contain the resulted row


expected output:
string(61) "SELECT field FROM table WHERE field = 1 LIMIT 0, 1"
array(1) {
  [0]=>
  array(2) {
    ["field"]=>
    string(1) "1"
    [0]=>
    string(1) "1"
    ["urlString"]=>
    string(44) "http://comequandofuoripiove.leonardo.it/foto"
    [1]=>
    string(44) "http://comequandofuoripiove.leonardo.it/foto"
    ["scheme"]=>
    string(4) "http"
    [2]=>
    string(4) "http"
    ["dominio"]=>
    string(32) "comequandofuoripiove.leonardo.it"
    [3]=>
    string(32) "comequandofuoripiove.leonardo.it"
    ["insertTimestamp"]=>
    string(13) "1177596562453"
    [4]=>
    string(13) "1177596562453"
    ["diffChk"]=>
    string(1) "1"
    [5]=>
    string(1) "1"
  }
}

Actual result:
--------------
$tmp->quetryString haven't the :placeholder binded to the value passed in execute(), so the query won't be a valid one and $tmp->fetchAll() will be empty

the same happens using PDOStatement::bindValue() or PDOStatement::bindParam()

the result seems not being related to a specific db driver (i tested with mysql and sqlite)

no exception is raised

script output:
string(61) "SELECT * FROM table WHERE field = :placeholder"
array(0) {
}



ps: if i remove the placeholder from prepare() and then try to still bind a value in execute() an exception is raised: "SQLSTATE[HY000]: General error: 25 bind or column index out of range"

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-06-07 09:54 UTC] andrea dot spacca at gmail dot com
in expected result the var_dumped array should be:
array(1) {
  [0]=>
  array(2) {
    ["field"]=>
    string(1) "1"
    [0]=>
    string(1) "1"
  }
}
 [2007-06-07 10:03 UTC] andrea dot spacca at gmail dot com
i haven't put the example in the code but the problem raises both with named and "anonymous" placeholders
 [2007-06-07 10:04 UTC] tony2001@php.net
>$tmp->quetryString haven't the :placeholder binded to the value
>passed in execute(), so the query won't be a valid one and 
>$tmp->fetchAll() will be empty

Binds are processed by the database drivers (where available), so $tmp->queryString contains original query, not the processed one.

And you code works just fine when table exists and contains requested data.


 [2007-06-07 10:15 UTC] andrea dot spacca at gmail dot com
> Binds are processed by the database drivers (where available), so
> $tmp->queryString contains original query, not the processed one.

i thought that PDOStatement::queryString will change will executing the PDOStatement.



> And you code works just fine when table
> exists and contains requested data.

obviously it isn't so, otherwise i hadn't open the bug

i haven't yet tested it on another enviroment, but on the one i'm working it doesn't work.

have i to open another bug showing the difference making the query strainght with no binding and without it? (the first works, not the latter)
 [2007-06-07 10:20 UTC] tony2001@php.net
>i thought that PDOStatement::queryString will change will executing
> the PDOStatement.

Well, you were wrong.

>obviously it isn't so, otherwise i hadn't open the bug
>i haven't yet tested it on another enviroment, but on the one i'm
>working it doesn't work.

Works just fine here.
(And apparently everywhere else, since this is a very basic functionality and you're the only one complaining.)

>have i to open another bug showing the difference making the query
>strainght with no binding and without it? (the first works, not the
>latter)

Sorry, I don't understand what you're talking about.
 [2007-06-07 12:49 UTC] andrea dot spacca at gmail dot com
> Works just fine here.

i've no doubt, otherwise you'd open the bug before me


> (And apparently everywhere else, since this is a very basic
> functionality and you're the only one complaining.)

that's false: i'm not the only one complaining, see http://pecl.php.net/bugs/bug.php?id=6030 and http://bugs.php.net/bug.php?id=36788. the fact that the complaints were ignored doesn't mean that the bug doesn't exist


> Sorry, I don't understand what you're talking about.

i'll be more explicit:
[code]
    try {
        $createSql = 'CREATE TABLE tbl (field)';
        $insertSql = array();
        $insertSql[1] = 'INSERT INTO tbl (field) VALUES (1)';
        $insertSql[2] = 'INSERT INTO tbl (field) VALUES (2)';
        $insertSql[3] = 'INSERT INTO tbl (field) VALUES (3)';
        $insertSql[4] = 'INSERT INTO tbl (field) VALUES (4)';
        $insertSql[5] = 'INSERT INTO tbl (field) VALUES (5)';
        $insertSql[6] = 'INSERT INTO tbl (field) VALUES (6)';
        $insertSql[7] = 'INSERT INTO tbl (field) VALUES (7)';

        $selectSql = 'SELECT field FROM tbl WHERE field BETWEEN 3 AND 5';
        $bindedSql = 'SELECT field FROM tbl WHERE field BETWEEN :first AND :last';

        $bindedValues = array(':first' => 3, ':last' => 5);
        
        $db = new PDO('sqlite:test.db');

        $db->exec($createSql);
        foreach ($insertSql as $query) {
            $db->exec($query);
        }
        
        $testNoBind = $db->query($selectSql);
        $rowsNoBind = $testNoBind->fetchAll();
        
        var_dump($rowsNoBind);
        
        $testWithBind = $db->prepare($bindedSql);
        $testWithBind->execute($bindedValues);
        $rowsWithBind = $testWithBind->fetchAll();
        
        var_dump($rowsWithBind);

        $db = NULL;
    } catch (Exception $e) {
        var_dump($e);
    }
[/code]

[expected]
array(3) {
  [0]=>
  array(2) {
    ["field"]=>
    string(1) "3"
    [0]=>
    string(1) "3"
  }
  [1]=>
  array(2) {
    ["field"]=>
    string(1) "4"
    [0]=>
    string(1) "4"
  }
  [2]=>
  array(2) {
    ["field"]=>
    string(1) "5"
    [0]=>
    string(1) "5"
  }
}
array(3) {
  [0]=>
  array(2) {
    ["field"]=>
    string(1) "3"
    [0]=>
    string(1) "3"
  }
  [1]=>
  array(2) {
    ["field"]=>
    string(1) "4"
    [0]=>
    string(1) "4"
  }
  [2]=>
  array(2) {
    ["field"]=>
    string(1) "5"
    [0]=>
    string(1) "5"
  }
}
[/expected]

[result]
array(3) {
  [0]=>
  array(2) {
    ["field"]=>
    string(1) "3"
    [0]=>
    string(1) "3"
  }
  [1]=>
  array(2) {
    ["field"]=>
    string(1) "4"
    [0]=>
    string(1) "4"
  }
  [2]=>
  array(2) {
    ["field"]=>
    string(1) "5"
    [0]=>
    string(1) "5"
  }
}
array(0) {
}
[/result]

is it more clear now?
 [2007-06-07 12:53 UTC] tony2001@php.net
mysql> CREATE TABLE tbl (field);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1

 [2007-06-07 12:54 UTC] andrea dot spacca at gmail dot com
> mysql> CREATE TABLE tbl (field);
> ERROR 1064 (42000): You have an error in your SQL syntax; check the
> manual that corresponds to your MySQL server version for the right
> syntax to use near ')' at line 1

please, pay attention: i'm using sqlite
 [2007-06-08 12:11 UTC] andrea dot spacca at gmail dot com
Solved on my own: it seems tha matter was with libsqlite. I switched back to 3.3.5 and now the binding works. The bug must be in libsqlite somewhere between 3.3.5 and 3.3.12
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu May 02 18:01:32 2024 UTC