今天看到csdn的bbs上有人问如何用json_decode解析gbk编码的串。
大家都知道,json都是utf8编码的。json_encode后的字符串都是会变成"\u4fe1\u6d77\u9f99"格式。
如下面的代码:
$arr = "信海龙"; echo json_encode($arr);
输出结果为:"\u4fe1\u6d77\u9f99"
如果你有一个符合json格式的gbk编码的字符串,如何使用json_decode进行解析呢?
答案其实很简单,呵呵。就是把字符串转为utf8编码既可。
你可以在gbk编码的文件中执行如下脚本,看效果。
<?php $json = '"信海龙"'; //一个符合json格式的gbk编码串 var_dump(json_decode($str)); //输出NULL $str = mb_convert_encoding($json, "utf8", "gbk"); var_dump(json_decode($str)); //输出 string(9) "信海龙" ?>
输出结果如下:
NULL string(9) "信海龙"
为什么只要转为utf8编码就可以呢?分析下源码。
在ext/json/json.c文件有json_decode的实现。代码如下:
PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC) /* {{{ */ { int utf16_len; zval *z; unsigned short *utf16; JSON_parser jp; utf16 = (unsigned short *) safe_emalloc((str_len+1), sizeof(unsigned short), 1); utf16_len = utf8_to_utf16(utf16, str, str_len); if (utf16_len <= 0) { if (utf16) { efree(utf16); } JSON_G(error_code) = PHP_JSON_ERROR_UTF8; RETURN_NULL(); } if (depth <= 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Depth must be greater than zero"); efree(utf16); RETURN_NULL(); } ALLOC_INIT_ZVAL(z); jp = new_JSON_parser(depth); if (parse_JSON(jp, z, utf16, utf16_len, assoc TSRMLS_CC)) { *return_value = *z; } else { double d; int type; long p; RETVAL_NULL(); if (str_len == 4) { if (!strcasecmp(str, "null")) { /* We need to explicitly clear the error because its an actual NULL and not an error */ jp->error_code = PHP_JSON_ERROR_NONE; RETVAL_NULL(); } else if (!strcasecmp(str, "true")) { RETVAL_BOOL(1); } } else if (str_len == 5 && !strcasecmp(str, "false")) { RETVAL_BOOL(0); } if ((type = is_numeric_string(str, str_len, &p, &d, 0)) != 0) { if (type == IS_LONG) { RETVAL_LONG(p); } else if (type == IS_DOUBLE) { RETVAL_DOUBLE(d); } } if (Z_TYPE_P(return_value) != IS_NULL) { jp->error_code = PHP_JSON_ERROR_NONE; } zval_dtor(z); } FREE_ZVAL(z); efree(utf16); JSON_G(error_code) = jp->error_code; free_JSON_parser(jp); }
注意方法中这行代码:
utf16_len = utf8_to_utf16(utf16, str, str_len);
也就是把utf8编码的串转换为utf16编码串,然后在调用parse_JSON方法解析。找个方法在JSON_parser.c中定义。
/* The JSON_parser takes a UTF-16 encoded string and determines if it is a syntactically correct JSON text. Along the way, it creates a PHP variable. It is implemented as a Pushdown Automaton; that means it is a finite state machine with a stack. */ int parse_JSON(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, int assoc TSRMLS_DC)
看注释,这个方法是需要接收utf16编码的。
技术交流
原文链接:在php中如何使用json_decode解析gbk编码的json字符串,转载请注明来源!