为什么 JSON_UNESCAPED_LINE_TERMINATORS 没有转义我的换行符?

Tho*_*mas 4 php json

根据文档,我希望在编码 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;仅\" 必须在字符串中转义。)

为什么这个选项没有按预期工作?

Tho*_*mas 9

[编辑] 我错误地阅读了 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 标准定义了一些符合应用程序应将其识别为行终止符的字符:

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
Run Code Online (Sandbox Code Playgroud)