备份数据库时是否需要使用addslashes()?

时间:2012-09-29 17:14:54

标签: php mysql database-backups

我正在使用显示here的代码,它在保存到文件之前对从数据库中提取的数据使用addslashes()。

$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()而不是addslashes()

4 个答案:

答案 0 :(得分:2)

插入db

将数据插入MySQL数据库时,您应该使用预准备语句或正确的转义函数,如mysql_real_escape_stringaddslashes与数据库无关,不应使用。 转义用作一般术语,但实际上涵盖了大量操作。这里似乎有两种使用逃逸的方法:

  1. 转义可以插入数据库的危险值
  2. 转义字符串引号以避免断字符串
  3. 大多数数据库转义函数除了转义引号外还有很多功能。他们逃脱非法字符以及像\ 0这样的隐形字符...这是因为根据您使用的数据库,有很多方法可以打破插入 - 而不仅仅是添加一个结束引号。

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

    输出/转储db值

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

    从db

    中选择值

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

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

    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) . '"';
    

答案 1 :(得分:2)

我认为你混合了两个问题。第一个问题是SQL Injection,为了防止这种情况,您必须转义进入数据库的数据。但到目前为止,有一种更好的方法可以做到这一点。使用预准备语句和绑定参数。 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 attacks这基本上允许可能的攻击者将代码注入你的网站。为防止出现这种情况,您应始终使用htmlspecialchars()显示包含您无法信任的可能信息的数据:

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

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

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

  

我应该使用addslashes()然后使用str_replace()将\“更改为”?

addslashes()听起来像是一种防止任何事情的蹩脚方式。所以不需要AFAICT。

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

他们不再被维护,社区已经开始deprecation process。请参阅red box?相反,您应该了解prepared statements并使用PDOMySQLi。如果您无法决定,this article将有助于选择。如果您想学习,here is a good PDO tutorial

答案 2 :(得分:0)

您应该存储数据而不进行修改。

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

答案 3 :(得分:0)

只需使用mysql_escape_string(),而不是像david walsh博客中所写的addslashes和ereg_replace。

试试吧它会更好。 :)