在php中如何使用json_decode解析gbk编码的json字符串

简介:
今天看到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 

看注释,这个方法是需要接收utf16编码的。


目录
相关文章
|
16天前
|
PHP 项目管理 开发者
深入解析PHP的命名空间和自动加载机制
【4月更文挑战第4天】 在PHP的编程世界中,命名空间和自动加载机制是构建大型应用程序时不可或缺的工具。本文将深入探讨这两个概念,揭示它们如何简化代码结构、避免类名冲突以及提高代码维护性。通过对PHP命名空间的由来、作用域和使用方法的细致剖析,以及对自动加载机制工作原理和应用实践的全面讲解,读者将获得有效管理复杂项目中依赖关系的能力。
|
25天前
|
JSON JavaScript 前端开发
C++ 智能指针与 JSON 处理:高级编程技巧与常见问题解析
C++ 智能指针与 JSON 处理:高级编程技巧与常见问题解析
255 0
|
7天前
|
存储 JSON JavaScript
「Python系列」Python JSON数据解析
在Python中解析JSON数据通常使用`json`模块。`json`模块提供了将JSON格式的数据转换为Python对象(如列表、字典等)以及将Python对象转换为JSON格式的数据的方法。
24 0
|
16天前
|
测试技术 PHP 开发者
PHP 7.4新特性深度解析
【4月更文挑战第4天】 本文将深入探讨PHP 7.4的新特性,包括预加载,数组解构,扩展的箭头函数等。我们将详细解释这些新特性的作用,以及如何在项目中使用它们来提高代码的效率和可读性。
|
18天前
|
JSON 数据格式
Json字符串与QVariantList 对象相互转换
Json字符串与QVariantList 对象相互转换
6 0
|
25天前
|
JSON JavaScript 数据格式
【深入探究C++ JSON库】解析JSON元素的层级管理与遍历手段
【深入探究C++ JSON库】解析JSON元素的层级管理与遍历手段
79 2
|
26天前
|
XML JSON API
深入解析C++ JSON库:nlohmann::json:: parse的内部机制与应用
深入解析C++ JSON库:nlohmann::json:: parse的内部机制与应用
44 0
|
26天前
|
运维 Linux Apache
LAMP架构调优(十)——Apache禁止指定目录PHP解析与错误页面优化
LAMP架构调优(十)——Apache禁止指定目录PHP解析与错误页面优化
197 2
|
JavaScript PHP
php和js中,utf-8编码转成base64编码
1、php下转化base64编码 php中,文本文件的编码决定了程序变量的编码,比如以下代码在不同编码的php文件中,展示的效果也是不一样的 如果文本文件是utf-8,则输出结果为:5Lil,而在gbk文件中的输出结果是:0c8= 注意:php中转换成base64编码时,和网页编码没有关系。
1638 0
|
7月前
|
关系型数据库 MySQL PHP
PHP 原生操作 Mysql
PHP 原生操作 Mysql
81 0

推荐镜像

更多