经过多年的阅读,是时候提出第一个问题:)
我的问题是,在将代码从mySQLi迁移到PDO后,我们遇到了一个问题,因为似乎PDO将撇号添加到查询中。
PHP代码就是这样:
$sort = $_GET['sort']; << table column name (mySQL VARCHAR only columns)
....
$query = 'SELECT * FROM table WHERE xxx > 0';
$query .= ' ORDER BY :sort ASC ;';
$qry_result= $db->prepare($query);
$qry_result->execute(array(':sort'=>$sort));
mysqli版本进展顺利,但现在查询(mysql日志文件)看起来像这样:
SELECT * FROM table where xxx > 0 ORDER BY 'SORT_VAR_VALUE' ASC;
^ 2 problems ^
因此表没有排序,因为排序顺序(从mySQL的角度来看)是错误的。
phpinfo()在“魔术”和“引用”btw上搜索没有任何结果。
任何想法??
答案 0 :(得分:2)
默认情况下,pdo将值绑定为字符串。
要解决此问题,您需要检查该列实际上是否为有效名称,然后将其添加到查询中,您可以通过以下方式执行此操作:
function validName($string){
return !preg_match("/[^a-zA-Z0-9\$_\.]/i", $string);
}
if(validName($sort)){
$db->prepare("SELECT * FROM table where xxx > 0 ORDER BY $sort ASC");
}
答案 1 :(得分:2)
PDO语句中的占位符仅用于值。如果要在查询中添加实际的SQL,则需要采用另一种方式。
首先,您应该清理$sort
并在查询中用反引号将其包围。
$sort = preg_replace('/^[a-zA-Z0-9_]/', '', $sort);
然后你可以双引号查询字符串,PHP将替换$sort
给你的值:
$query = "SELECT * FROM table WHERE xxx > 0 ORDER BY `$sort` ASC";
或者您可以像preg_replace
一样替换它:
$query = 'SELECT * FROM table WHERE xxx > 0 ORDER BY `:sort` ASC';
$query = preg_replace('/:sort/', $sort, $query, 1);
我会使用preg_replace
方法,因为如果您将preg_replace
的结果分配给另一个变量而不是覆盖原始变量,则可以重复使用该查询。
答案 2 :(得分:-1)
使用PDO,不可能在WHERE语句中绑定其他变量。因此,您必须对您订购的列的名称进行硬编码。 见How do I set ORDER BY params using prepared PDO statement? 或Can PHP PDO Statements accept the table or column name as parameter?进一步解释。