信息资讯综合思念体

解决json_encode中文会编码为unicode,兼容php5.4之前的版本

编码后也可以正确的用json_decode进行解码

1、使用正则

/**
 * 解决json_encode的中文兼容问题(虽然看似兼容5.2不过没测试过)
 * 
 * @param  array|stdClass $value 被编码的数据
 * 
 * @return 编码为json字符串的数据
 */
function json_encode_unescaped_unicode($value)
{
    static $callback;

    if (version_compare(PHP_VERSION, '5.4.0', '<')) {
        if (!is_callable($callback)) {
            $callback = create_function('$matchs', 
                'return iconv(\'UCS-2BE\', \'UTF-8\', pack(\'H4\', $matchs[1]));'
            );
        }
        
        $str = json_encode($value);
        $str = preg_replace_callback("#\\\u([0-9a-f]{4})#i", $callback, $str);

        return $str;
    } else {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}


性能测试(环境:MACBOOKPRO 13 2015款)

代码:

<?php

////////////////////////////////////////////////////////////////
/// 解决 5.4以下的encode中文没有 JSON_UNESCAPED_UNICODE 选项的问题
////////////////////////////////////////////////////////////////

$num = 0;
$count = 0;
$time = microtime(true);

function my_log()
{
    global $count, $time, $num;

    if (microtime(true) - $time >= 1) {
        printf("次数:%d\n", $count);

        $count = 0;
        $time = microtime(true);
        $num++;
    }
}

register_tick_function('my_log');

/**
 * 解决json_encode的中文兼容问题(虽然看似兼容5.2不过没测试过)
 * 
 * @param  array|stdClass $value 被编码的数据
 * 
 * @return 编码为json字符串的数据
 */
function json_encode_unescaped_unicode($value)
{
    static $callback;

    if (version_compare(PHP_VERSION, '5.4.0', '<')) {
        if (!is_callable($callback)) {
            $callback = create_function('$matchs', 
                'return iconv(\'UCS-2BE\', \'UTF-8\', pack(\'H4\', $matchs[1]));'
            );
        }
        
        $str = json_encode($value);
        $str = preg_replace_callback("#\\\u([0-9a-f]{4})#i", $callback, $str);

        return $str;
    } else {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

$data = array(
    'qwe' => '你好世界',
    'asd' => array(
        '神奇了',
        'zxc' => array(
            's' => '那么再深一点'
        )
    )
);

declare(ticks = 1)
{
    while ($num < 10) {
        json_encode_unescaped_unicode($data);
        $count++;
    }
}


php5.3:(每秒encode次数)

次数:39405

次数:39829

次数:40229

次数:40300

次数:40425

次数:41298

次数:38226

次数:40405

次数:40758

次数:39853


php5.6:(每秒encode次数)

次数:380351

次数:376383

次数:384623

次数:385797

次数:381795

次数:374920

次数:366855

次数:380634

次数:373909

次数:379061


性能上的差异肯定是有的毕竟又用正则又用iconv的。

从测试上看,9倍左右的差距应该还包含php5.6本身就比5.3快的原因。

不过这个差距是有点大,那么还是赶紧升级php5.6吧,现在的大趋势都是7.1了,还在用老款干啥呀,各种新特性高性能在等着各位phper!(跑题了)


2、先用urlencode编码中文,在json_encode之后再用urldecode转换回来

function json_encode_unescaped_unicode($value, $is_deep = false)
{
    if (version_compare(PHP_VERSION, '5.4.0', '<')) {
        foreach ($value as $k => &$v) {
            if (is_string($v)) {
                $v = urlencode($v);
            } else if (is_array($v)) {
                $v = json_encode_unescaped_unicode($v, true);
            }
        }

        return $is_deep ? $value : urldecode(json_encode($value));
    } else {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

同样的测试,这个性能没高多少,而且还带着个递归

php5.3:

次数:72744

次数:72718

次数:74101

次数:75071

次数:75672

次数:73354

次数:75474

次数:73025

次数:74453

次数:75715


原创文章转载请注明出处哟!

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-BlogPHP 1.5.1 Zero Theme By 爱墙纸

百度资讯综合思念体对有机生命接触用人形终端界面 那就是
晋ICP备15000230号