@walkor Demo里面提供的JsonProtocal.php 在處理中文上有點問題
原因在于strlen并不能正確返回長度
例如:
$zhStr = '中文混合eng!';
echo strlen($zhStr); // 輸出:18
要換成mb_strlen 我也是查手冊才知道的
同理還有substr函數(shù)。要換成mb_substr
由于我不了解php 才看了一天而已。但是改成下面這樣就能工作了。
老大你看下。是否要加更多的邏輯。
class JsonProtocol
{
// 根據(jù)首部四個字節(jié)(int)判斷數(shù)據(jù)是否接收完畢
public static function check($buffer)
{
// 讀取首部四個字節(jié)
$buffer_data = unpack('Ntotal_length', $buffer);
// 得到這次數(shù)據(jù)的整體長度(字節(jié))
$total_length = $buffer_data;
// 已經(jīng)收到的長度(字節(jié))
$recv_length = mb_strlen($buffer,'utf-8');
if($total_length>$recv_length)
{
// 還有這么多字節(jié)要接收
return $total_length - $recv_length;
}
// 接收完畢
return 0;
}
// 打包
public static function encode($data)
{
// 選用json格式化數(shù)據(jù)
$buffer = json_encode($data);
// 包的整體長度為json長度加首部四個字節(jié)(首部數(shù)據(jù)包長度存儲占用空間)
$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);
// 得到這次數(shù)據(jù)的整體長度(字節(jié))
$total_length = $buffer_data;
echo $total_length;
// json的數(shù)據(jù)
$json_string = mb_substr($buffer, 4, $total_length-4, 'utf-8');
echo $json_string;
return json_decode($json_string, true);
}
}
客戶端是多樣的。很多客戶端不會去編碼成unicode再發(fā)送。而是直接用utf8了。
jsonprotocol在處理中文上確實有問題。
如果一定要客戶端 禁止傳遞中文字符。那我不好說什么了
1、workerman默認都是按照字節(jié)計算長度,框架本身不會考慮編碼問題
2、jsonprotocol傳輸中文明文也是可以的,但是utf8中文字符必須按照3個字節(jié)來算,而不是1,不然就會出問題。
3、strlen是返回字符串的字節(jié)長度,而不是按照utf8等特定編碼的字符串的長度。所以
$zhStr = '中文混合eng!';
echo strlen($zhStr); // 輸出:18
返回的長度是沒問題的。
最后,你的問題應(yīng)該是混淆了字符串的字節(jié)長度和按照編碼計算的長度,也就是客戶端沒有按照uft8中文字符是占3個字節(jié)來算長度導(dǎo)致的。這并不是jsonprotocol的問題。