根据文档,我希望在编码 JSON 时JSON_UNESCAPED_LINE_TERMINATORS保留\n未转义的换行符 ( ) 字符,以便保留实际的换行符:
JSON_UNESCAPED_LINE_TERMINATORS(整数)行终止符在提供
时保持未转义。JSON_UNESCAPED_UNICODE它使用与 PHP 7.1 之前相同的行为,但没有此常量。从 PHP 7.1.0 开始可用。
最小的例子:
$ php -r 'echo json_encode(["foo" => "bar\nbaz"], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS) . "\n";'
{"foo":"bar\nbaz"}
Run Code Online (Sandbox Code Playgroud)
我期望:
{"foo":"bar
baz"}
Run Code Online (Sandbox Code Playgroud)
(请注意,这是有效的 JSON;仅\且" 必须在字符串中转义。)
为什么这个选项没有按预期工作?
[编辑] 我错误地阅读了 JSON 规范:字符串内未编码的换行符不是有效的 JSON。从 U+0000 到 U+001F 的控制字符必须进行转义。PHP 不包含未编码的内容是正确的,尽管文档显然可以改进!
我必须去源头才能找到答案。本文中的“行终止符”仅指晦涩的 Unicode 代码点 U+2028 行分隔符和 U+2029 段落分隔符:
/* Escape U+2028/U+2029 line terminators, UNLESS both
JSON_UNESCAPED_UNICODE and
JSON_UNESCAPED_LINE_TERMINATORS were provided */
} else if ((options & PHP_JSON_UNESCAPED_UNICODE)
&& ((options & PHP_JSON_UNESCAPED_LINE_TERMINATORS)
|| us < 0x2028 || us > 0x2029)) {
Run Code Online (Sandbox Code Playgroud)
这与 Unicode定义的行终止符相冲突:
Unicode 标准定义了一些符合应用程序应将其识别为行终止符的字符:
Run Code Online (Sandbox Code Playgroud)LF: Line Feed, U+000A VT: Vertical Tab, U+000B FF: Form Feed, U+000C CR: Carriage Return, U+000D CR+LF: CR (U+000D) followed by LF (U+000A) NEL: Next Line, U+0085 LS: Line Separator, U+2028 PS: Paragraph Separator, U+2029