如何用 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;
}
}
我正在使用 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;
}
}