PHP JSON_ERROR_UTF16 错误排查笔记

JSON_ERROR_UTF16错误是PHP7.0加入的,在decode含有错误的unicode编码时会有此错误,比如:

<?php
json_decode('["\ude00\ud83d"]');
echo json_last_error();   // 10 
echo JSON_ERROR_UTF16; // 10,JSON_ERROR_UTF16值为10

正确的unicode是\ud83d\ude00(是一个emoji:😀 )。

一位朋友在调用第三方接口时遇到的此问题,由于我自己也没有相关的错误处理经验,花了很久才搞明白是unicode错误的问题。因为JSON_ERROR_UTF16是在php7.0加入的,所以我特意在php5.6中试了试,json字符串是可以成功decode的,无法解析的unicode会变成\uFFFD(FFFD是未知,无法表示的意思),菜菜的我看了看PHP5.6的json_decode源码,一行没看懂,又去看了看PHP7.0的json_decode源码,恩~~, 这回能看懂个大概。

(以下内容都是我猜测的,才疏学浅,如有错误,还请大佬指教。)

在php7.0中,是使用re2c生成的json语法扫描器,在json_scanner.re文件中匹配了unicode的高级代理区和低级代理区(utf16是无法表示全部的unicode字符的,所以utf16是变长的,就产生了“代理区”的概念,可以看一下我之前分享的编码知识#27),代码如下:

UTF16_4 = UTFPREF [dD] [89abAB] HEX{2} UTFPREF [dD] [c-fC-F] HEX{2} ;

由于“\ud83d\ude00”高低级代理区的颠倒,导致无法匹配到正确的unicode,所以 json_last_error() === JSON_ERROR_UTF16。

参考:
en.wikipedia.org/wiki/Re2c
github.com/php/php-src/blob/PHP-7....
www.php.net/manual/en/json.constan...
www.unicode.org/charts/PDF/UFFF0.p...

原文:github.com/woodongwong/notes/issue...

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!