现在的位置: 首页 > 综合 > 正文

HESSIONPHP2.2 double类型bug解决

2013年04月24日 ⁄ 综合 ⁄ 共 2679字 ⁄ 字号 评论关闭
//HESSIONPHP double类型转码错误
//最终解决方法为
//Hessian2Parser.php下185行改为如下
function double4($code, $num){
return 0.001 * $this->parseInt($code, $num);
/*
$b = $this->read(4);
$num = (ord($b[0]) << 24) + 
(ord($b[1]) << 16) +
(ord($b[2]) << 8) +
ord($b[3]);
return 0.001 * $num;
*/
// from the java implementation, this makes no sense
// why not just use the float bytes as any sane language and pack it like 'f'?
}

//第200行改为
	function double64($code, $num){
		$bytes = $this->read(8);
		//if(HessianUtils::$littleEndian)
			$bytes = strrev($bytes);
		//$double = unpack("dflt", strrev($bytes));
		$double = unpack("dflt", $bytes);
        return $double['flt'];
	}

OK.解决

发现第二个bug
hessian2Parser.php中的
double1函数
接收-3时会被转换成253
解决方法

175行(double1函数中)加入如下代码
if(ord($bytes) >= 128){
return (ord($bytes) - 256);
}
原因看如下代码理解
<?php

/**
 * byte数组与字符串转化类
 * @author zikie
 * Created on 2011-7-15 
 */

class Bytes {
    
    /**
     * 转换一个String字符串为byte数组
     * @param $str 需要转换的字符串
     * @param $bytes 目标byte数组
     * @author Zikie
     */
     
    public static function getBytes($str) {

        $len = strlen($str);
        $bytes = array();
           for($i=0;$i<$len;$i++) {
               if(ord($str[$i]) >= 128){
                   $byte = ord($str[$i]) - 256;
               }else{
                   $byte = ord($str[$i]);
               }
            $bytes[] =  $byte ;
        }
        return $bytes;
    }
    
    /**
     * 将字节数组转化为String类型的数据
     * @param $bytes 字节数组
     * @param $str 目标字符串
     * @return 一个String类型的数据
     */
     
    public static function toStr($bytes) {
        $str = '';
        foreach($bytes as $ch) {
            $str .= chr($ch);
        }

           return $str;
    }
    
    /**
     * 转换一个int为byte数组
     * @param $byt 目标byte数组
     * @param $val 需要转换的字符串
     * @author Zikie
     */
    
    public static function integerToBytes($val) {
        $byt = array();
        $byt[0] = ($val & 0xff);
        $byt[1] = ($val >> 8 & 0xff);
        $byt[2] = ($val >> 16 & 0xff);
        $byt[3] = ($val >> 24 & 0xff); 
        return $byt;
    }
    
    /**
     * 从字节数组中指定的位置读取一个Integer类型的数据
     * @param $bytes 字节数组
     * @param $position 指定的开始位置
     * @return 一个Integer类型的数据
     */
     
    public static function bytesToInteger($bytes, $position) {
        $val = 0;
        $val = $bytes[$position + 3] & 0xff; 
        $val <<= 8;
        $val |= $bytes[$position + 2] & 0xff;
        $val <<= 8;
        $val |= $bytes[$position + 1] & 0xff;
        $val <<= 8;
        $val |= $bytes[$position] & 0xff;
        return $val;
    }

    /**
     * 转换一个shor字符串为byte数组
     * @param $byt 目标byte数组
     * @param $val 需要转换的字符串
     * @author Zikie
     */
    
    public static function shortToBytes($val) {
        $byt = array();
        $byt[0] = ($val & 0xff);
        $byt[1] = ($val >> 8 & 0xff);
        return $byt;
    }
    
    /**
     * 从字节数组中指定的位置读取一个Short类型的数据。
     * @param $bytes 字节数组
     * @param $position 指定的开始位置
     * @return 一个Short类型的数据
     */
     
    public static function bytesToShort($bytes, $position) {
        $val = 0;
        $val = $bytes[$position + 1] & 0xFF; 
        $val = $val << 8;
        $val |= $bytes[$position] & 0xFF;
        return $val;
    }
    
}
?>

其实其本质就是java的byte[]类型与char类型的转换

请看下表

char             -128 ~ +127        (1 Byte)
short             -32767 ~ + 32768    (2 Bytes)
unsigned short     0 ~ 65536        (2 Bytes)
int             -2147483648 ~ +2147483647   (4 Bytes)
unsigned int         0 ~ 4294967295    (4 Bytes)
long == int
long long         -9223372036854775808 ~ +9223372036854775807    (8 Bytes)
double         1.7 * 10^308        (8 Bytes)

char类型的取值范围是 -128 ~ + 127

但是byte等同于 unsigned char 没有负数

所以其表示负数的方法是+256

如 -3 其存入byte的值就是253

再转换为char时需要-256后再用ascII转换

3.hessianPHP解析效率低下,对于复杂的对象,hessianPHP也做的类似java的映射,但是过于复杂的对象解析消耗时间太长,所以对象尽量简单越好

抱歉!评论已关闭.