簡體   English   中英

PHP json_decode 不適用於由 Node 12 格式良好的 JSON.stringify 引起的單個未配對代理

[英]PHP json_decode does not work with single unpaired surrogate caused by Node 12 well-formed JSON.stringify

Node 12 現在使用格式良好的 JSON.stringify ,它為單獨的代理輸出轉義序列。 當有一個單獨的代理被轉義時,PHP 無法對此進行 json_decode。

以 Node.js 中的以下代碼示例為例。

var a = '𝘥𝘦𝘴𝘪𝘨𝘯𝘦𝘳 𝘢𝘯𝘥 𝘪𝘭𝘭𝘶𝘴𝘵𝘳𝘢𝘵𝘰𝘳';
JSON.stringify(a.slice(0, 15));

// Node 10 output: 
'"𝘥𝘦𝘴𝘪𝘨𝘯𝘦�"';

// Node 12 output:
'"𝘥𝘦𝘴𝘪𝘨𝘯𝘦\\ud835"'

然后將此響應作為 JSON 發送到 PHP 服務器並進行解碼。 這是發生錯誤的地方。 Node10 的輸出曾經可以與 PHP json_decode 一起正常工作,但它不再與 Node12 的輸出一起工作。

我簡化了 NODE->PHP 示例,見下文。

<?php
$string = '{"string": "𝘥𝘦𝘴𝘪𝘨𝘯𝘦\\ud835"}';
var_dump(json_decode($string, false, 512, JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_IGNORE | JSON_INVALID_UTF8_SUBSTITUTE));

// Output:
Fatal error: Uncaught JsonException: Single unpaired UTF-16 surrogate in unicode escape in phptest.php:36
Stack trace:
#0 phptest.php(36): json_decode('{"string": "\xF0\x9D\x98...', false, 512, 7340032)
#1 {main}
  thrown in phptest.php on line 36

我希望以下選項JSON_INVALID_UTF8_IGNOREJSON_INVALID_UTF8_SUBSTITUTE在 PHP 7.3+ 中與 json_decode 一起使用,但它根本沒有幫助。 JSON_THROW_ON_ERROR實際上會拋出一個錯誤,以便於調試。

問題出在 Javascript 中。

a 中的字符串包含多字節字符。 使用 a.slice(0, 15) 你會得到 15 個字節,而不是 15 個字符並創建一個無效的 utf-8 字符串。 多字節字符可能不會被破壞。

更新:

我認為選項 JSON_INVALID_UTF8_IGNORE 和 JSON_INVALID_UTF8_SUBSTITUTE 用於 json_encode () 而不是為 json_decode () 清理無效的 JSON。 干凈的解決方案是在 Javascript 頁面上提供有效的 JSON。

骯臟的解決方案是嘗試用 PHP 糾正無效的 JSON:

$json = preg_replace_callback(
  '~\\\u[a-d0-9]{4}~iu',
  function($found){
    if(json_decode('"'.$found[0].'"')){
      return $found[0];
    }
    return "";  //or "?"
  },
  $invalidJson
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM