JsonProtocal.php处理utf8编码的中文问题

guoxj

@walkor Demo里面提供的JsonProtocal.php 在处理中文上有点问题
原因在于strlen并不能正确返回长度
例如:
$zhStr = '中文混合eng!';
echo strlen($zhStr); // 输出:18
要换成mb_strlen 我也是查手册才知道的
同理还有substr函数。要换成mb_substr
由于我不了解php 才看了一天而已。但是改成下面这样就能工作了。
老大你看下。是否要加更多的逻辑。

class JsonProtocol
{
    // 根据首部四个字节(int)判断数据是否接收完毕
    public static function check($buffer)
    {
        // 读取首部四个字节
        $buffer_data = unpack('Ntotal_length', $buffer);
        // 得到这次数据的整体长度(字节)
        $total_length = $buffer_data;
        // 已经收到的长度(字节)
        $recv_length = mb_strlen($buffer,'utf-8');
        if($total_length>$recv_length)
        {
            // 还有这么多字节要接收
            return $total_length - $recv_length;
        }
        // 接收完毕
        return 0;
    }

    // 打包
    public static function encode($data)
    {
        // 选用json格式化数据
        $buffer = json_encode($data);
        // 包的整体长度为json长度加首部四个字节(首部数据包长度存储占用空间)
        $total_length = 4 + mb_strlen($buffer,'utf-8');
        return pack('N', $total_length) . $buffer;
    }

    // 解包
    public static function decode($buffer)
    {
        echo $buffer;
        $buffer_data = unpack('Ntotal_length', $buffer);
        // 得到这次数据的整体长度(字节)
        $total_length = $buffer_data;
        echo $total_length;
        // json的数据
        $json_string = mb_substr($buffer, 4, $total_length-4, 'utf-8');
        echo $json_string;
        return json_decode($json_string, true);
    }
}
阅读 2997
5个回答

walkor

合法的json里面不会包含中文的,中文会转换成类似 u5723\u8bde\u8282\u5343\u4e07\u597d\u793c\u5927\u5949\u9001
这样的字符

  • 暂无评论
guoxj

不一定哦。
{"E": "中文"} 也是合法的。
只要是utf8编码即可。
jsonlint.com 可以在此验证下

  • 暂无评论
walkor

jsonprotocol 验证过的,没有问题的

workerman中buffer长度都是按照字节计算,不是按照utf8编码或者其它编码的字符串的长度来计算的

另外浏览器json_encode和php json_encode 都是把utf8字符变成unicode来传递的,不会传递原始的中文字符

  • 暂无评论
guoxj

客户端是多样的。很多客户端不会去编码成unicode再发送。而是直接用utf8了。
jsonprotocol在处理中文上确实有问题。
如果一定要客户端 禁止传递中文字符。那我不好说什么了

  • 暂无评论
walkor

1、workerman默认都是按照字节计算长度,框架本身不会考虑编码问题
2、jsonprotocol传输中文明文也是可以的,但是utf8中文字符必须按照3个字节来算,而不是1,不然就会出问题。
3、strlen是返回字符串的字节长度,而不是按照utf8等特定编码的字符串的长度。所以

$zhStr = '中文混合eng!';
echo strlen($zhStr); // 输出:18

返回的长度是没问题的。

最后,你的问题应该是混淆了字符串的字节长度和按照编码计算的长度,也就是客户端没有按照uft8中文字符是占3个字节来算长度导致的。这并不是jsonprotocol的问题。

  • 暂无评论