如何用 PDO::quote() 替换 mysql_escape_string

How to replace mysql_escape_string by PDO::quote()

我正在使用 http://www.elated.com/articles/cms-in-an-afternoon-php-mysql/ 学习 PHP,它一直非常有用,但无法用我的头脑来替换已弃用的 mysql_escape_string

我关注了 Whosebug 上的现有对话: 我认为一个可能的解决方案是将 quote() 实现为 $conn->quote($order) 以避免 SQL 注入,但是我看不出它应该在代码中发挥什么作用。

或者您认为 $st = $conn->prepare( $sql ); 已经在这里完成工作了吗?

  public static function getList( $numRows=1000000, $order="publicationDate DESC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );

/*$sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles
        ORDER BY " . mysql_escape_string($order) . " LIMIT :numRows";*/

$sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles
        ORDER BY " . $order . " LIMIT :numRows";

$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
$st->execute();
$list = array();

while ( $row = $st->fetch() ) {
  $article = new Article( $row );
  $list[] = $article;
}

所以你的问题是 PDO 只允许绑定值,使用 PDO::Quote 既不是安全的选择也不是有效的选择。

Or do you think that $st = $conn->prepare( $sql ); is already doing the job here?

不,它不做这项工作,PDO::prepare 只准备绑定值,不准备硬编码值。

因为您的 $order 正在接受用户的输入(很容易被操纵),最安全的选择是创建一组允许的白名单订单类型。如果来自 $order 的输入在白名单数组中,您可以继续准备并执行语句。

编辑:考虑到评论中的 link,这是我对您当前代码的替代方案:

<?php
public static function getList( $numRows=1000000, $order="publicationDate DESC" ) {

 $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);

 //Your whitlelist of order bys.
 $order_whitelist = array("publicationDate DESC", "publicationDate ASC", etc..);

 // see if we have such a name, if it is not in the array then $order_check will be false.
 $order_check = array_search($order, $order_whitelist); 

if ($order_check !== FALSE)
 {

 $sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles
    ORDER BY " . $order . " LIMIT :numRows";

 $st = $conn->prepare($sql);
 $st->bindValue(":numRows", $numRows, PDO::PARAM_INT);
 $st->execute();
 $list = array();

 while ($row = $st->fetch())
     {
     $article = new Article($row);
     $list[] = $article;
     }
 }