9

Code Sample

$query = $this->db->prepare( $sql );                  // prepare sql
$query->bindParam( 'start', $start, PDO::PARAM_INT ); // bind start
$query->bindParam( 'end', $end, PDO::PARAM_INT );     // bind end
$query->bindParam( 'language', $this->language );     // bind language
$query->bindValue( 'keyword', "%$keyword%" );         // bind keyword

var_dump( $end );
$query->execute();
var_dump( $end );

Output

int 2
string '2' (length=1)

But... if I switch the order of binds...

$query = $this->db->prepare( $sql );                  // prepare sql
$query->bindParam( 'language', $this->language );     // bind language
$query->bindValue( 'keyword', "%$keyword%" );         // bind keyword
$query->bindParam( 'start', $start, PDO::PARAM_INT ); // bind start
$query->bindParam( 'end', $end, PDO::PARAM_INT );     // bind end

var_dump( $end );
$query->execute();
var_dump( $end );

Output

int 2
int 2

PHP Version: 5.3.8 on Windows

Can anyone explain why this is happening?

4
  • 2
    i'm willing to bet this is a bug in pdo Commented Jul 17, 2012 at 12:35
  • 5.3.8 was released almost a year ago - Can anybody reproduce this on PHP > 5.4? Commented Jul 17, 2012 at 12:44
  • I think most people still use 5.3 and 5.2 - it should at least be fixed in the latest 5.3.x. So can anyone test this in 5.3.14? Commented Jul 17, 2012 at 12:49
  • 1
    There is a comment mentioning this problem back in 2009 Commented Jul 17, 2012 at 13:18

3 Answers 3

1

Try turning of emulation for preparing statements

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

Sign up to request clarification or add additional context in comments.

Comments

1

Checked this with PHP 5.3.13 - two versions of your code gives me:

int 2
string '2' (length=1)

Additionally, with using bindValue() instead of bindParam() two versions of code gives me:

int 2
int 2

p.s. I prefer work with bindValue() and not mix it with bindParam(). Using bindParam() doesn't gives any performance improvements. Some people thinks that passing by values and passing by pointer in PHP works as in C/C++, but this is wrong thinking. Using bindParam() may lead to bugs that hard to find them when they occurs.

Comments

-1

I know this has been said before but I'll write a note on it too because I think it's important to keep in mind:

If you use PDO bindParam to do a search with a LIKE condition you cannot put the percentages and quotes to the param placeholder %:keyword%.

This is WRONG:

"SELECT * FROM `users` WHERE `firstname` LIKE '%:keyword%'";

The CORRECT solution is to leave clean the placeholder like this:

"SELECT * FROM `users` WHERE `firstname` LIKE :keyword";

And then add the percentages to the php variable where you store the keyword:
$keyword = "%".$keyword."%";

And finally the quotes will be automatically added by PDO when executing the query so you don't have to worry about them.

So the full example would be:

<?php
    // Get the keyword from query string
    $keyword = $_GET['keyword'];
    // Prepare the command
    $sth = $dbh->prepare('SELECT * FROM `users` WHERE `firstname` LIKE :keyword');
    // Put the percentage sing on the keyword
    $keyword = "%".$keyword."%";
    // Bind the parameter
    $sth->bindParam(':keyword', $keyword, PDO::PARAM_STR);
?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.