无法在PHP中替换回车和换行符

3

我从前端获取了一个带有换行符的字符串。它保存在一个数组中,看起来像这样:

[address] => Array (
    [0] => Foo
Bar
)

在将数组写入SQL数据库之前,我会使用json_encode()对其进行编码:

$string = json_encode( $string, JSON_UNESCAPED_UNICODE );

这将数组转换为:
{"address":["Foo\r\nBar"]}

很遗憾,如果不转义,数据库不支持 \r 或 \n,所以会去掉这些字符。

  1. 因此,第一个问题是,是否有函数可以正确转义字符串,使其可以正常写入数据库而不丢失换行符?

  1. 我没有找到相关的函数,所以我尝试使用 str_replace 函数将 \r\n 替换为 \\n。函数如下:

$string = str_replace(["\r\n","\r","\n"], "\\n", $string);

但是这并没有起作用。我不知道为什么。这个函数本身是可以工作的,因为我曾经试图将 "n" 替换为 "bla",它也起作用了。但是当我试图替换反斜杠时,它就无法找到任何要替换的内容。我不知道是否使用了某些“特殊”的反斜杠字符或者其他可能会出现的情况。

这真的让我抓狂。所以我希望有人能帮助我解决问题。提前谢谢。


只需使用PDO,不必担心任何问题...真的...它并不难。 - Dimi
如果您正在使用 str_replace 来转义内容,那么您做错了。请使用适当的数据库转义函数。这取决于您使用的接口。最起码要使用像 $db->escape(...) 这样的东西。使用准备好的语句和占位符值会更好。这些是有效的。而您的代码则不是。 - tadman
如果您正在使用WordPress,请查看WPDB文档以获取更多详细信息。 - tadman
你是如何将数据传递到数据库的呢?能否贴出你的代码以及执行代码后存储在数据库中的结果数据? - Umair Shah Yousafzai
3个回答

3

问题 : 你的 str_replace 没有效果,因为你使用了 双引号

解决方案 : 你应该用 单引号 替换你的 双引号,然后神奇的事情就会发生 :D

$string = str_replace(['\r\n','\r','\n'], '\\n', $string);

额外有用的信息:如果想更深入地了解双引号单引号之间的区别,可以查看以下链接:

PHP中单引号和双引号字符串的区别是什么?


非常感谢,这个方法很有效。还要感谢您提供的额外信息,我会仔细阅读的。不过,为了让它正常工作,我甚至不得不使用三个反斜杠:$string = str_replace(['\r\n','\r','\n'], '\\n', $string); 您有任何想法是为什么吗? - Chi
我不明白你的意思,因为这只是将字符串中的字符替换为其他字符,所以任何你写入字符串输出的内容都可以。 - Umair Shah Yousafzai

1
这取决于您如何将字符串插入数据库。无论如何,您都需要正确转义它。
如果您使用PDO,可以像这样实现:
$conn = new PDO(.....);
$sql_str = $conn->quote($string);
$conn->exec("INSERT INTO table (str_value) {$sql_str}");

或者,更好的方法是使用预处理语句:
$conn = new PDO(.....);
$stm = $conn->prepare("INSERT INTO table (str_value) :value");
$stm->execute(array(':value' => $string));

希望这能行。

1

直接在数据库中存储JSON?呕吐!

但是,如果你真的必须这样做,那么为什么要改变数据的表示方式?当你将其通过JSON解码器运行回来时,你会得到原始数据。问题只在于如何将其转换为安全格式以便插入到数据库中。

从PHP数组创建它意味着在保存数据之前检查数据内容没有任何借口(不是直接从Javascript提供数据的任何有效或可原谅的方式)。

有没有我可以使用的函数来正确转义字符串?

是的,有几个 - 但你没有告诉我们你正在使用哪个API。这不是某种神奇的技巧来解决你目前所面临的问题 - 适当地转义你写入数据库的任何数据对于防止SQL注入至关重要。

除了Alex提到的PDO方法外,您可以使用已弃用的mysql扩展中的mysql_escape_string/mysql_real_escape_string或在mysqli过程式代码中使用mysql_escape_string / mysqli_real_escape_stringmsqli_prepare + mysqli_bind_param。mysqli函数还具有面向对象的表示形式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接