执行PDO查询将绑定参数从整数更改为字符串


Executing PDO Query changes bound parameter from integer to string

代码示例

$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 );

输出

int 2
string '2' (length=1)

但是如果我切换绑定的顺序。。。

$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 );

输出

int 2
int 2

PHP版本:5.3.8在Windows上

有人能解释为什么会发生这种事吗?

尝试切换模拟以准备语句

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

用PHP 5.3.13检查了这一点-您的代码的两个版本给了我:

int 2
string '2' (length=1)

此外,使用bindValue()而不是bindParam(),两个版本的代码给了我:

int 2
int 2

p.s。我更喜欢使用bindValue(),而不是将其与bindParam()混合使用。使用bindParam()不会带来任何性能改进。有些人认为在PHP中传递值和传递指针与在C/C++中一样有效,但这是错误的想法。使用bindParam()可能会导致错误出现时很难找到。

我知道以前说过这句话,但我也会写一条注释,因为我认为记住这一点很重要:

如果使用PDO bindParam在LIKE条件下进行搜索,则无法将百分比和引号放在参数占位符%:keyword%中。

这是错误的:

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

正确的解决方案是保持占位符的清洁,如下所示:

"SELECT * FROM `users` WHERE `firstname` LIKE :keyword";
And then add the percentages to the php variable where you store the keyword:
$keyword = "%".$keyword."%";

最后,PDO在执行查询时会自动添加引号,这样您就不必担心它们了。

因此,完整的例子是:

<?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);
?>