0

可能重复:
如何将 pdo 的准备好的语句用于 order by 和 limit 子句?

我正在使用 PDO,因为它被推荐为 PHP 数据库连接的方式。但与此同时,我痴迷于保护我的查询,以确保我的系统尽可能免受黑客攻击。

PDO 和准备好的语句是一个很好的方法,但我有几个问题。我有一个自定义过滤系统,需要我手动构建查询。例如,这个:

$query=$pdo->prepare('SELECT * FROM log WHERE username=?');
$result=$query->execute(array($_GET['username']));

这行得通,一切都很好 - PDO 处理确保 $_GET 变量不会损害我的查询。

但是当我需要逃避其他事情时该怎么办?例如,如果我有这种情况,我只想返回五条记录:

$query=$pdo->prepare('SELECT * FROM log WHERE username=? LIMIT 5');
$result=$query->execute(array($_GET['username']));

这再次有效。但是如果限制值也来自 $_GET 怎么办?如何逃脱它?

为此,我首先想到我必须手动构建查询并使用 PDO::quote() 方法,如下所示:

$query='SELECT * FROM log WHERE username=? LIMIT '.$pdo->quote($_GET['limit']);

但这不起作用,因为它在限制器周围放置了引号,这会破坏查询。

有没有像 mysql_real_escape_string() 那样使用 PDO 转义的正确方法?由于后者从未在结果变量周围加上引号,但我无法使用 quote() 来阻止这种行为。

另一种选择是构建我自己的转义器,但这违背了使用 PDO 准备好的语句开头的目的(准备好的语句本身总是在值​​周围加上引号)。

编辑:我还尝试将值转换为引号中的整数,如下所示:

$pdo->quote((int)$value,PDO::PARAM_INT);

但它 - 仍然 - 在它周围加上引号。与 intval() 相同。

如果我必须做类似这种习惯的原始事情,为什么会如此积极地建议和推荐使用 PDO?我真的不想为这样的情况编写一个消毒方法,并希望没有任何东西被破坏或受到损害。

4

2 回答 2

2

您关心整数值。与$_GET字符串一样,您可以将其转换为具有强制转换或%d格式的整数sprintf

$query = $pdo->prepare(
    'SELECT * FROM log WHERE username=? LIMIT ' . (int) $_GET['page']
);

$query = $pdo->prepare(
    sprintf('SELECT * FROM log WHERE username=? LIMIT %d', $_GET['page'])
);

如果您确实需要一个字符串,那么quote()您已经写过的函数是合适的。

于 2012-04-26T14:08:05.087 回答
-3

这是一个很棒的初学者教程。教育你自己。

为什么你应该使用 PHP 的 PDO...

于 2012-04-26T14:09:46.320 回答