php - PDO 多个命名占位符不检索数据

标签 php mysql pdo

如果只有一个命名的占位符用于准备好的语句,我目前编写的代码可以正常工作,但如果查询有多个条件,它不会从数据库返回任何结果。

例如:

$query = array();
$query['columns'] = array('*');
$query['tables'] = array('esl_comments');
$query['where'] = array(
    'esl_comments.commentVisible' => array('=', 'Y')
);

工作正常。但如果我尝试:

$query = array();
$query['columns'] = array('*');
$query['tables'] = array('esl_comments');
$query['where'] = array(
    'esl_comments.commentVisible' => array('=', 'Y'),
    'esl_comments.commentID' => array('=', '1'),
);

(注意附加的 commentID 参数)尽管 mySQL 数据库中有满足条件的数据,但它无法返回任何内容。

我写的PDO代码是:

$sql ='SELECT ';
                foreach($query['columns'] as $column){ //What columnns do we want to fetch?
                    $sql.=$column . ", ";
                }
                $sql = rtrim($sql, " ,");
                $sql .=' FROM '; //Which tables will we be accessing?
                foreach($query['tables'] as $tables){
                    $sql.=$tables . ", ";
                }
                $sql = rtrim($sql, " ,"); //Get rid of the last comma
                $sql .=' WHERE ';

                if(array_key_exists('where', $query)) //check if a where clause was provided
                {
                    $fieldnames = array_keys($query['where']);
                    $count = 0;
                    $size = sizeof($fieldnames);
                    $bindings = array();
                    foreach($query['where'] as $where){

                        $cleanPlaceholder = str_replace("_", "", $fieldnames[$count]);
                        $cleanPlaceholder = str_replace(".", "", $cleanPlaceholder);
                        $sql.=$fieldnames[$count].$where[0].":".$cleanPlaceholder." AND ";
                        $bindings[$cleanPlaceholder]=$where[1];
                        $count++;
                    }
                    $sql = substr($sql, 0, -5);  //Remove the last AND
                }
                else{ //no where clause so set it to an always true check
                    $sql.='1=1';
                    $bindings=array('1'=>'1'); //Provide default bindings for the statement
                }

                $sql .= ';'; //Add the semi-colon to note the end of the query
                echo $sql . "<br/><br/>";
            //  exit();
                $stmt = $this->_connection->prepare($sql);

                foreach($bindings as $placeholder=>$bound){
                    echo $placeholder . " - " . $bound."<br/>";
                    $stmt->bindParam($placeholder, $bound);
                }

                $result = $stmt->execute();
                echo $stmt->rowCount() . " records<br/>";

                $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

我正在动态构建查询,因此我通过去除句号和下划线来清理占位符 - 因此使用了“cleanPlaceholder”变量。

正在生成的查询如下所示:

SELECT * FROM esl_comments WHERE esl_comments.commentVisible=:eslcommentscommentVisible AND esl_comments.commentID=:eslcommentscommentID;

被绑定(bind)的参数是这样的:

eslcommentscommentVisible - Y
eslcommentscommentID - 1

最佳答案

bindParam 需要引用

问题是由您在 foreach 循环中绑定(bind)参数的方式引起的。

foreach($bindings as $placeholder=>$bound){
    echo $placeholder . " - " . $bound."<br/>";
    $stmt->bindParam($placeholder, $bound);
}

bindParam 需要引用。它将变量而不是值绑定(bind)到语句。由于 foreach 循环中的变量在每次迭代开始时被重置,因此只有最后一个对 $bound 的引用保持不变,您最终将所有占位符绑定(bind)到它。

这就是为什么您的代码在 $query['where'] 仅包含一个条目时有效,但在包含多个条目时失败的原因。

您可以通过两种方式解决问题:

通过引用传递

foreach($bindings as $placeholder => &$bound) {  //pass $bound as a reference (&)
    $stmt->bindParam($placeholder, $bound);     // bind the variable to the statement
}

按值传递

使用bindValue代替bindParam:

foreach($bindings as $placeholder => $bound) {  
    $stmt->bindValue($placeholder, $bound);     // bind the value to the statement
}

关于php - PDO 多个命名占位符不检索数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13667807/

相关文章:

PHP无限滚动拉随机结果?

php - 包含和 MySQL

PHP 数组 - `array_splice` 问题

javascript - 使用 Ajax 从 javascript 到 php 的数组 - Mootools

php - 使用 mySQL 在 PHP 中 SQL 不返回结果

mysql - MySQL脚本中显示的方 block 字符

mysql - 显示外键等于某个值的所有表

PHP和PDO类问题

php - 无法在 Mac 上连接到 MySQL——缺少 mysql.sock 文件

php - 如何清理复选框?