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

0

@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);
}
}
已邀请:

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的问题。

要回复问题请先登录注册