$reporter = "John O'Hara";
$result = $mysqli->execute_query("SELECT * FROM users WHERE name=?", [$reporter]);
$row = $result->fetch_assoc(); // or while (...)
其他查询部分,如SQL关键字、表名或字段名、运算符等,必须通过白色名单过滤。 有时我们必须添加一个变量来表示查询的另一部分,例如关键字或标识符(数据库、表或字段名)。这是一个罕见的情况,但最好做好准备。 在这种情况下,必须根据脚本中显式编写的值列表检查变量。我在另一篇文章Adding a field name in the ORDER BY clause based on the user's choice中解释了这一点: 不幸的是,PDO没有标识符(表和字段名)的占位符,因此开发人员必须手动过滤它们。这样的过滤器通常被称为“白色名单”(我们只列出允许的值),而不是“黑名单”,我们列出不允许的值。 因此,我们必须在PHP代码中显式列出所有可能的变体,然后从中进行选择。 下面是一个例子:
$orderby = $_GET['orderby'] ?: "name"; // set the default value
$allowed = ["name","price","qty"]; // the white list of allowed field names
$key = array_search($orderby, $allowed, true); // see if we have such a name
if ($key === false) {
throw new InvalidArgumentException("Invalid field name");
}
方向应该使用完全相同的方法,
$direction = $_GET['direction'] ?: "ASC";
$allowed = ["ASC","DESC"];
$key = array_search($direction, $allowed, true);
if ($key === false) {
throw new InvalidArgumentException("Invalid ORDER BY direction");
}
5条答案
按热度按时间b09cbbtk1#
在任何MySQL语句中添加PHP变量的规则都是简单明了的:
1.使用预处理语句
这个规则涵盖了99%的查询,尤其是你的查询。任何表示 SQL数据文字 * 的变量(或者,简单地说-SQL字符串或数字)必须通过准备好的语句添加。 没有例外 *。
这种方法包括四个基本步骤
下面是如何使用所有流行的PHP数据库驱动程序来实现这一点:
使用
mysqli
添加数据文本当前的PHP版本允许您在一个调用中执行prepare/bind/execute:
如果你的PHP版本很旧,那么prepare/bind/execute必须显式完成:
代码有点复杂,但所有这些操作符的详细解释可以在我的文章How to run an INSERT query using Mysqli中找到,以及一个大大简化该过程的解决方案。
对于SELECT查询,您可以使用与上面相同的方法:
但同样,如果你的PHP版本很旧,你需要执行prepare/bind/execute例程,并添加一个
get_result()
方法的调用,以获得一个熟悉的mysqli_result
,你可以从它以通常的方式获取数据:使用PDO添加数据文本
在PDO中,我们可以将绑定和执行部分结合起来,这非常方便。PDO还支持命名占位符,有些人觉得这非常方便。
2.使用白色名单过滤
其他查询部分,如SQL关键字、表名或字段名、运算符等,必须通过白色名单过滤。
有时我们必须添加一个变量来表示查询的另一部分,例如关键字或标识符(数据库、表或字段名)。这是一个罕见的情况,但最好做好准备。
在这种情况下,必须根据脚本中显式编写的值列表检查变量。我在另一篇文章Adding a field name in the ORDER BY clause based on the user's choice中解释了这一点:
不幸的是,PDO没有标识符(表和字段名)的占位符,因此开发人员必须手动过滤它们。这样的过滤器通常被称为“白色名单”(我们只列出允许的值),而不是“黑名单”,我们列出不允许的值。
因此,我们必须在PHP代码中显式列出所有可能的变体,然后从中进行选择。
下面是一个例子:
方向应该使用完全相同的方法,
在这样的代码之后,
$direction
和$orderby
变量都可以安全地放入SQL查询中,因为它们要么等于允许的变量之一,要么会抛出错误。关于标识符,最后要提到的是,它们还必须根据特定的数据库语法进行格式化。对于MySQL,标识符周围应该有
backtick
个字符。因此,我们的orderby示例的最终查询字符串将是nfeuvbwi2#
为了避免SQL注入,插入语句中的be
dl5txlt93#
**最好的选择是准备好的语句。**乱用引号和转义是一项更难的工作,也很难维护。迟早你会不小心忘记引用某些东西,或者两次转义同一个字符串,或者搞砸类似的事情。可能要过好几年你才能找到那种虫子。
http://php.net/manual/en/pdo.prepared-statements.php
oyxsuwqo4#
$type中的文本被直接替换到插入字符串中,因此MySQL得到:
请注意,测试中没有引号,您需要像这样将其放入:
我还建议你阅读SQL injection,因为如果你不清理正在使用的数据,这种类型的参数传递很容易被黑客攻击:
hlswsv355#
答案很简单:
你可以随意定义
$name
另一种方式,复杂的方式,是这样的: