PDO 将撇号添加到 mySQL 查询

PDO adds the apostrophe to the mySQL query

经过多年的阅读,是时候提出第一个问题了:)

我的问题是,在将代码从 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  ^

因此 table 未排序,因为排序顺序(从 mySQL 的角度来看)是错误的。

phpinfo() 没有在 "magic" 和 "quotes" 上搜索任何结果。

有什么想法吗??

默认情况下,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");
}

使用 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? 进一步解释。

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 的结果分配给另一个变量而不是覆盖原始变量,它允许您重用查询。