php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38546 bindParam incorrect processing of bool types
Submitted: 2006-08-22 15:00 UTC Modified: 2017-08-15 13:14 UTC
Votes:29
Avg. Score:4.4 ± 0.8
Reproduced:24 of 25 (96.0%)
Same Version:6 (25.0%)
Same OS:7 (29.2%)
From: selecter at gmail dot com Assigned:
Status: Closed Package: PDO MySQL
PHP Version: 5.2.4 OS: Gentoo Linux x86_64
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: selecter at gmail dot com
New email:
PHP Version: OS:

 

 [2006-08-22 15:00 UTC] selecter at gmail dot com
Description:
------------
The code below leads to unclear error Fatal error: : in /var/www/localhost/htdocs/crash.php on line 33

But if I pass int values instead of bool, this code works fine.

Instead of:
'show_email' => (bool) 1,
'show_smiles' => (bool) 1,

Write:
'show_email' => 1,
'show_smiles' => 1,

I noticed that because I get those values like this:
'show_email' => CheckBox::isOn('show_email'),

'show_smiles' => CheckBox::isOn('show_smiles'),
which return bool values...

Reproduce code:
---------------
<?php
try{

    $dsn = 'mysql:host=localhost;dbname=test';

    $db = new PDO($dsn, 'root', 'pass');

}catch(PDOException $e){

	trigger_error($e->getMessage(), E_USER_ERROR);

}

$prefs = array(

            	'show_email' => (bool) 1,

            	'show_smiles' => (bool) 1,

            	'timezone_offset' => 0,

            	'messages_on_page' => 5,
            	'uid', 6

);

    		$st = $db->prepare("UPDATE preferences SET show_email=?, show_smiles=?, timezone_offset=?, messages_on_page=? WHERE uid=?");

		$st->bindParam(1, $prefs['show_email'], PDO::PARAM_BOOL);

        $st->bindParam(2, $prefs['show_smiles'], PDO::PARAM_BOOL);

        $st->bindParam(3, $prefs['timezone_offset'], PDO::PARAM_INT);

        $st->bindParam(4, $prefs['messages_on_page'], PDO::PARAM_INT);
			$id = 6;
        $st->bindParam(5, $id, PDO::PARAM_INT);    	
    	if(($num=$st->execute()) === FALSE){

      	$einfo = $db->errorInfo();

        $einfo = $db->errorCode.': '.$einfo[2];
			?><pre><?php        
        debug_print_backtrace();
        ?></pre><?php      
        trigger_error($einfo, E_USER_ERROR);
    	}else{

        	echo 'ok';

        }
?>


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-08-22 15:01 UTC] selecter at gmail dot com
- changed incorrect summary
 [2006-08-22 15:11 UTC] tony2001@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip


 [2006-08-22 15:54 UTC] selecter at gmail dot com
Still reproducable. Here's the code:
<?php
try{

    $dsn = 'mysql:host=localhost;dbname=test';

    $db = new PDO($dsn, 'root', 'pass');

}catch(PDOException $e){

	trigger_error($e->getMessage(), E_USER_ERROR);

}

$prefs = array(

	'show_email' => (bool) 1,

	'show_smiles' => (bool) 1,

	'timezone_offset' => 0,

	'messages_on_page' => 5,
	'uid', 6

);

		$query = "CREATE TABLE prefs(

	        uid MEDIUMINT UNSIGNED NOT NULL,

            show_email BOOL NOT NULL,

            show_smiles BOOL NOT NULL,

            timezone_offset TINYINT NOT NULL,

            messages_on_page TINYINT UNSIGNED NOT NULL

	    )";
		$query = "INSERT INTO prefs VALUES(6, 1, 1, 0, 5)";

	    $db->exec($query);

    		$st = $db->prepare("UPDATE prefs SET show_email=?, show_smiles=?, timezone_offset=?, messages_on_page=? WHERE uid=?");

		$st->bindParam(1, $prefs['show_email'], PDO::PARAM_BOOL);

        $st->bindParam(2, $prefs['show_smiles'], PDO::PARAM_BOOL);

        $st->bindParam(3, $prefs['timezone_offset'], PDO::PARAM_INT);

        $st->bindParam(4, $prefs['messages_on_page'], PDO::PARAM_INT);
			$id = 6;
        $st->bindParam(5, $id, PDO::PARAM_INT);    	
    	if(($num=$st->execute()) === FALSE){

      	$einfo = $db->errorInfo();

        $einfo = $db->errorCode.': '.$einfo[2];
			?><pre><?php        
        debug_print_backtrace();
        ?></pre><?php      
        trigger_error($einfo, E_USER_ERROR);
    	}else{

        	echo 'ok';

        }
?>
 [2006-08-22 16:29 UTC] tony2001@php.net
I get:
---
array(1) {
  [0]=>
  string(5) "00000"
}

Notice: Undefined property:  PDO::$errorCode in /tmp/1.php on line 62

Notice: Undefined offset:  2 in /tmp/1.php on line 62
<pre></pre>
Fatal error: :  in /tmp/1.php on line 66
---

No crashes. valgrind doesn't show anything wrong there.
 [2006-08-22 16:42 UTC] selecter at gmail dot com
That's what you get: Fatal error: :  in /tmp/1.php on line 66
That's all that matters...

Instead of:
'show_email' => (bool) 1,
'show_smiles' => (bool) 1,

Write:
'show_email' => 1,
'show_smiles' => 1,

and the query will be executed successfully.
 [2006-08-22 16:59 UTC] tony2001@php.net
First of all, there is no crash.
Fatal error is the result of your trigger_error() call.
PDOStatement::execute() fails because MySQL API doesn't support boolean parameters (though they can be "emulated" through PDO).

I'm leaving this to the maintainer to decide.
 [2007-02-06 16:35 UTC] hans at velum dot net
I don't think that anyone said this was crashing.  It certainly is a fatal error in that it doesn't work.  And using PDO w/ Exception error mode will (should!) eventually result in a fatal error for the app that's using it.

This is clearly a PDO bug.  If any application that uses PDO has to check to see if MySQL is being used & then alter that type params passed to bindValue() then there is NO VALUE in having the small set of *abstracted* types that PDO does provide.
 [2007-02-06 16:38 UTC] hans at velum dot net
This looks to be the same issue as: http://pecl.php.net/bugs/bug.php?id=9919
 [2007-04-11 15:26 UTC] tobias dot woell at it-basis dot de
Suggestion for workaround (works with PHP 5.1.6 and MySql 4.1.1):
$tmp = (int) $this->getDue_Date_IsWeek();
$stmt->bindParam(':Due_Date_IsWeek' , $tmp , PDO::PARAM_BOOL );
 [2007-09-05 14:02 UTC] jani@php.net
Fixed the version number. Please don't invent your own versions. The first char in the version field is supposed to be the major version number!! I'm assuming this still exist in PHP 5.2.4. If not, close this.
 [2009-04-25 14:38 UTC] jani@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2009-05-03 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2017-08-15 03:37 UTC] kernins at gmail dot com
Still reproducible on 7.1.8. 

Using \PDO::PARAM_BOOL in bindValue() still leads to execute() failing silently, with no exception being thrown. From mysql side, stmt just gets closed without being executed.

>PDOStatement::execute() fails because MySQL API doesn't support boolean parameters
I, as a user of PDO, shouldn't care about such details at all. Otherwise, what's a point in using it? If bools aren't supported by mysql API, then PDO should either convert to int, or throw an exception.

Trivial bug. More that 10 yrs. Still not fixed.
Shame on you!
 [2017-08-15 13:14 UTC] adambaratz@php.net
-Status: No Feedback +Status: Re-Opened -Package: PDO related +Package: PDO MySQL -Assigned To: wez +Assigned To:
 [2019-02-01 11:59 UTC] jh_walker at outlook dot com
Still present in PHP 7.2; how has such a trivial little issue stayed open for over 12 years?

PDO should be able to convert boolean value to integers for passing to MySQL... what's the point in retaining the `PHP::PARAM_BOOL` type if it does not work when passed a boolean value?
 [2019-03-05 19:00 UTC] henry dot paradiz at gmail dot com
This bug also needs to have PDO::ATTR_EMULATE_PREPARES set to false.

Personally I think it should throw an exception.
 [2019-03-06 06:36 UTC]
The following pull request has been associated:

Patch Name: pdo_mysql: Fix boolean parameter binds failing when not using emulation.
On GitHub:  https://github.com/php/php-src/pull/3921
Patch:      https://github.com/php/php-src/pull/3921.patch
 [2019-06-07 07:50 UTC] nikic@php.net
Automatic comment on behalf of camporter1@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7d1aa7534d756477d45f8fa63b5467589ccca031
Log: Fixed bug #38546
 [2019-06-07 07:50 UTC] nikic@php.net
-Status: Re-Opened +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC