hessianPHP中文乱码解决

1.HessianPHP的DateTime问题
我在家使用时发现了问题,php上显示错误“Cannot redeclare class DateTime”。经调查发现,从PHP5.2开始php有了叫DateTime的类型,见文章http://laughingmeme.org /2007/02/27/looking-at-php5s-datetime-and-datetimezone/,这就与HessianPHP包定义 的DateTime类冲突,所以导致了上面的错误。我在公司用的是php 5.0.x的版本没问题,在家用了php5.2.x的版本就有问题。
这就有问题,现在很多客户已使用了PHP的新版本,直接用就不行了,而HessianPHP也没有更新。所以目前只能自己解决。解决方法是:将 HessianPHP包中使用的DateTime的地方改成别的名字,如HessianDateTime,经我测试没问题了。
这个问题在其开源项目已有人提到,见http://sourceforge.net/tracker/index.php?func=detail& amp;aid=1804163&group_id=126933&atid=707220,问题解决了,基本做法也是将两个文件里的名 字改了。

2. HessianPHP的中文字符编码问题
Hessian调用的中文问题,Java之间调用没有乱码问题,与其它主要语言(C#,Python)应该也是没问题的(未测试),但与PHP直接传输中 文字符串就有问题,双向都有问题。经研究,HessianPHP的实现有问题。另外,PHP本身对处理中文字符串有问题,PHP没有很好的支持 Unicode,PHP中的字符串是按字节处理的 。
目前解决方法,需要在php客户端和java服务端都做urlencode和urldecode编解码。因为编码后的传输只有ascii字符了,而ascii字符传输没问题。这样就解决了中文问题。
但这种方法有几个缺点:
  1. 需要客户端和服务端双方都要对中文做编解码。
  2. 服务端是向所有客户提供服务的,不只是php客户端。采用此方法后将使以后其它客户端访问此服务也需要编解码。



我对HessianPHP处理中文字符串错误,研究结果如下:
在HessianPHP包中,负责发送String是要用到HessianWriter类writeStringData方法,此类定义在Protocal.php文件中:
function writeStringData($value){
$this->stream .= pack('n',strlen($value));
$this->stream .= utf8_encode($value);
}
在Hessian协议中字符串是要以utf8编码方式传输的,所以这里原作者用了utf8_encode函数。但问题是utf8_encode是将 ISO-8859-1 编码的字符串转换为 UTF-8 编码,问题就是这里。如果我们用的php源文件本身就是utf8编码的,那么其中的中文字符串已经是utf8编码了(php只把字符串看作字节),再用 utf8_encode函数就等于把已经是utf8的内容又做了一次编码,所以收到的内容当然是乱码了。我在这里把utf8_encode函数去掉,直接 用$value,收到的就不是乱码。如我发送“韩国恺”,收到的内容是“韩国恺z”,可以看出问题就在这里。但又有问题了,“韩国恺”的后面多个一个 “z”,说明别的地方自然就少了一个“z”,“z”其实表示一个终结符,服务器端报错 “com.caucho.hessian.io.HessianProtocolException: hello: expected end of call ('z') at end of stream.”。推测可知,这个问题是前面计算字符串长度strlen($value)有误导致的问题,根据Hessian字符串映射的定义, 长度是按照16bit字符长度计算的,并不一定等于字节的数量strlen($value)。也就是说,长度应该是Unicode的字符数。而PHP中的 strlen函数其实只是得到了字符串的字节数,不是真正的字符数,中文是多字节的,当然有问题。清楚原因了,我们可以解决这个问题。很简单,将 strlen函数替换为我后面定义的utf8_strlen函数即可,utf8_strlen函数返回的是这个utf8编码的字符串的真正字符数,作用如同Java中String的length方法一样。最后,经我修改后,终于解决了php发送中文的乱码问题。修改后的代码如下:
function writeStringData($value){
$this->stream .= pack('n',utf8_strlen($value));
$this->stream .= $value;
}
另外,HessianPHP中,负责解析字符串的HessianParser类的readString方法也有问题,导致php收到的中文字符串也有问 题,变成了问号。有经验的人很清楚,一般将UTF-8/GBK等多字节编码转换为ASCII/ISO-8859-1的单字节编码时,不兼容的部分就会变成 问号了。通过查看Protocal.php文件HessianParser类的readString方法,可以看出作者已经考虑根据UTF-8读取字节的 问题,但是该方法的最后一句话“return utf8_decode($string);”就出了问题。utf8_decode函数是把字符串转成ISO-8859-1的编码,那当然中文就成了问 号!最后,只要改为“return $string;”就可以了。
终于,修改后的Hessian的PHP实现可以按照Hessian协议标准正常的收发中文字符串了!这是完全透明的。
这种方法才是从根本上解决了Hessian PHP的问题,完全没有前面解决方法的所有缺点。有点麻烦的是,要自己修改源文件的几个地方。我会向作者反映这个问题,希望以后版本能够改进,继续支持开源。


以上可以看出,HessianPHP的实现者在国际化(I18N)方面的理解上不够,没有正确理解php中utf8_encode和 utf8_decode函数。还可以看出PHP不支持Unicode真的很烂,比起其它Java等支持Unicode的语言要多走一些弯路。
实际上,PHP与Java的xml-rpc调用上也存在类似的问题,这可不是Java的问题。

我认为Hessian的PHP支持不好。下载的最新HessianPHP包中,显示有“HessianPHP 1.0.5 RC2 (PHP4 & 5) Release Date: 2005-12-29”,从06年开始就没有更新过了,只有少数人在维护,且支持处于不活跃状态。另外,文档不够详细,细节需要看源文件。如果遇到什么问 题,只能我们自己解决了,这是一种额外的负担。

提示:
除了使用Hessian作为rpc协议外,使用基本的RESTful的方式也可以很轻松的实现服务,比如通过http get或post方法把参数传过来,返回特定的xml或json格式的结果。这种方式非常简单、灵活,且语言、平台无关,不需要额外对中文编解码。



function utf8_strlen($str)
{
$count = 0;

for($i = 0; $i
< strlen($str); $i++)
{
$value = ord($str[$i]);

if($value > 127)
{
if($value >= 192 &&
$value <= 223)
$i++;
elseif($value >= 224
&& $value <= 239)
$i = $i + 2;

elseif($value >= 240 && $value <= 247)
$i = $i +
3;
else
die('Not a UTF-8 compatible
string');
}

$count++;
}


return $count;
}

http://hi.baidu.com/heroofhero/blog/item/049d8c1e5843c9c1a6866903.html

已标记关键词 清除标记
课程简介: 历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页