0

我正在使用此处显示的代码,它在保存到文件之前对从数据库中获取的数据使用了 addlashes()。

$row[$j] = addslashes($row[$j]);

我的问题是为什么以及我需要使用它吗?我认为您在保存到数据库时会这样做,而不是相反。当我将上述脚本的结果与 phpMyAdmin 的导出结果进行比较时,包含序列化数据的字段是不同的。我想知道导入回数据库时是否会导致任何问题?

脚本:

'a:2:{i:0;s:5:\"Hello\";i:1;s:5:\"World\";}'

phpMyAdmin 导出:

'a:2:{i:0;s:5:"Hello";i:1;s:5:"World";}'

更新

插入数据库时​​所有数据都被转义。

从 mysql 更改为 mysqli。

SQL 文件输出如下:

INSERT INTO test (foo, bar) VALUES (1, '\'single quotes\'\r\n\"double quotes\"\r\n\\back slashes\\\r\n/forward slashes/\r\n');

解决方案

使用 $mysqli->real_escape_string() 而不是 addlashes()

4

4 回答 4

2

插入数据库

将数据插入 MySQL 数据库时,您应该使用准备好的语句或适当的转义函数,例如mysql_real_escape_string. addslashes与数据库无关,不应使用。转义是一个通用术语,但实际上涵盖了大量的操作。这里似乎正在讨论转义的两种用途:

  1. 转义可能插入数据库的危险值
  2. 转义字符串引号以避免损坏的字符串

大多数数据库转义函数不仅仅是转义引号。它们会转义非法字符以及 \0 等不可见字符 ...这是因为根据您使用的数据库,有很多方法可以破坏插入 - 而不仅仅是添加右引号。

因为似乎有人错过了我关于提及 PDO 的评论,所以我将在这里再次提及。使用 PDO 或其他一些数据库抽象系统以及准备好的语句要好得多,这是因为您不再需要担心转义您的值。

输出/转储数据库值

在提到的备份您的数据库脚本中,原始编码器addslashes用作快速速记,以确保 mysql 转储中的输出字符串格式正确并且不会在重新插入时中断。它与安全无关。

从数据库中选择值

即使您在插入数据库时​​转义了您的值,当将该数据写回任何使用字符串的导出文件时,您也需要再次转义引号。这只是因为您希望保护您的字符串以使其格式正确。

将转义数据插入数据库时​​,使用的“转义序列”将转换回其原始值。例如:

INSERT INTO table SET field = "my \"escaped\" value"

一旦进入数据库,该值实际上将是:

my "escaped" value

因此,当您将其从数据库中拉出时,您将收到:

my "escaped" value

所以当你需要把它放在一个格式化的字符串/转储中,一个解析器将读回的转储,你需要做一些转义来正确格式化它:

$value_from_database = 'my "escaped" value';

echo '"' . $value_from_database . '"';

将产生:

"my "escaped" value"

这将破坏任何正常的字符串解析器,因此您需要执行以下操作:

$value_from_database = 'my "escaped" value';

echo '"' . addslashes($value_from_database) . '"';

生产:

"my \"escaped\" value"

但是,如果是我,我只会针对双引号并转义:

$value_from_database = 'my "escaped" value';

echo '"' . str_replace('"', '\\"', $value_from_database) . '"';
于 2012-09-29T17:46:10.627 回答
2

我认为你混合了两个问题。第一个问题是SQL 注入,为了防止这种情况,您必须转义进入数据库的数据。然而,到目前为止,有一种更好的方法可以做到这一点。使用准备好的语句和绑定参数。PDO 示例:

// setup a connection with the database
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');    
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// run query
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = :name');    
$stmt->execute(array(':name' => $name));

// get data
foreach ($stmt as $row) {
    // do something with $row
}

您必须担心的另一件事是XSS 攻击,它基本上允许可能的攻击者将代码注入您的网站。为防止这种情况,htmlspecialchars()在显示包含您不信任的可能信息的数据时,您应始终使用:

echo htmlspecialchars($dataFromUnsafeSource, ENT_QUOTES, 'UTF-8');

插入数据库时​​所有数据都被转义。

当使用准备好的语句和绑定参数时,这不再需要了。

我应该使用 addlashes() 然后使用 str_replace() 将 \" 更改为 "吗?

addslashes()听起来像是防止任何事情的糟糕方法。所以不需要AFAICT。

关于访问数据库的另一个注意事项,如果您仍在使用旧mysql_*功能:

它们不再被维护并且社区已经开始了弃用过程。看到红框了吗?相反,您应该了解准备好的语句并使用PDOMySQLi。如果你不能决定,这篇文章将有助于选择。如果你想学习,这里有一个很好的 PDO 教程

于 2012-09-29T17:52:37.810 回答
0

您应该在不修改数据的情况下存储数据。

在输出数据或将它们“放入”其他数据(例如数据库查询中)时,您应该执行所需的转义。

于 2012-09-29T17:30:32.517 回答
0

只需使用 mysql_escape_string() 代替 david walsh 的博客中所写的 addlashes 和 ereg_replace 即可。

只是尝试它会更好。:)

于 2012-09-29T17:33:11.653 回答