首先也是最重要的:
请不要使用mysql_*新代码中的函数。它们不再被维护并已被正式弃用。请参阅red box?学习关于准备好的陈述相反,并使用PDO, or MySQLi - 本文将帮助您决定哪个。如果您选择PDO,这是一个很好的教程.
遵循这个建议变得比以往任何时候都更加重要,ext/MySQL 现已被弃用,使用它会发出E_DEPRECATED
从 PHP 5.5 开始的错误,有一天它将从核心语言中完全删除。话虽如此,以下内容适用于所有数据库的所有驱动程序。
对于本解释的其余部分,我将假设您由于某种原因无法使用 MySQLi 或 PDO(请注意only这里令人满意的原因是它们不可用,“我不知道如何使用它们”不是借口)并且您被迫使用 ext/MySQL。如果您能够使用任一较新的驱动程序,那么您就能够使用准备好的语句,并且这些都不适用。所以,考虑到这一点...
接下来我们看看之前的答案有什么问题。这以转义用户输入为中心。它用mysql_real_escape_string()
这是一种毫无意义的方式。这应该用于转义单个字符串文字,绝对不能用于其他用途。它不能用于有效转义数字,也不能用于转义 SQL 中不仅仅是值的部分。
以下两个代码片段显示了执行此操作的正确方法,具体取决于数据是什么以及最重要的是其类型。
如果值是字符串(通常是CHAR
or VARCHAR
field):
// First create an array of individually escaped values with quotes added
$deds = array();
foreach ($_POST['deductions'] as $ded) {
$deds[] = "'".mysql_real_escape_string($ded)."'";
}
// Now join them together in an SQL syntax
$deds_joined = join('), (', $deds);
// Now they can safely be used in the query
$query = "INSERT INTO mytable (deduction) VALUES ($deds_joined)";
但通常在这种情况下,这些值只是数字,在这种情况下,我们需要做的就是确保 PHP 使用正确的数据类型表示它们,因为当它们转换回字符串时,它们将自动安全。在查询中使用:
// First convert the array values to integers
$deds = array();
foreach ($_POST['deductions'] as $ded) {
$deds[] = (int) $ded;
}
// Now join them together in an SQL syntax
$deds_joined = join('), (', $deds);
// Now they can safely be used in the query
$query = "INSERT INTO mytable (deduction) VALUES ($deds_joined)";
这段代码显然假设数据是整数类型,只需更改浮点数即可轻松处理(int)
投射到(float)
.
还值得注意的是,字符串方法也可以安全、成功地用于数值,因为 MySQL 也会将值转换为正确的类型。但一般来说,在查询中使用正确的类型表示传递数据会更好、更高效。