`
Robinson
  • 浏览: 91270 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

关于Hessian的PHP支持问题

    博客分类:
  • PHP
阅读更多

Hessian主页:http://hessian.caucho.com/
Hessian PHP实现主页:http://hessianphp.sourceforge.net/
Hessian PHP开源项目主页:http://sourceforge.net/projects/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函数替换为我后面定义的de style="font-family: Arial; ">utf8_strlen函数即可, de>de style="font-family: Arial; ">utf8_strlen函数返回的是这个utf8编码的字符串的真正字符数,作用如同Java中String的length方法一样。最后,经我修改后,终于解决了 de>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格式的结果。这种方式非常简单、灵活,且语言、平台无关,不需要额外对中文编解码。



de style="font-family: Arial; ">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;
}
de>

分享到:
评论

相关推荐

    hessian php与java通讯demo源码

    Hessian支持多种语言,包括Java、PHP、Python等,这使得跨平台的集成变得容易。 在提供的压缩包中,我们有三个文件:`java_client.rar`、`java_server.rar`和`php-client.rar`。这些文件分别代表了Java客户端、Java...

    S25-hessian反序列化1

    【S25-Hessian反序列化1】是一个关于Java中Hessian序列化库的讨论,主要涉及Hessian与原生Java序列化的差异以及在Spring框架中的应用。Hessian是一种二进制序列化协议,旨在提高远程过程调用(RPC)的效率。与原生Java...

    Hessian学习笔记

    Hessian协议支持Java、C++、PHP等多种编程语言,使得跨平台的交互变得更加便捷。 Hessian的学习主要涉及以下几个核心知识点: 1. **二进制序列化**:Hessian使用高效的二进制格式进行序列化和反序列化,与基于文本...

    java调用hessianphp写得web service

    HessianPHP是一个实现了Hessian协议的PHP库,它允许PHP服务器端创建Web服务,而这些服务可以被Java或其他支持Hessian的客户端调用。在本示例中,"ExampleImp.java"和"Example.java"代表Java端的服务接口和服务实现,...

    二进制Web服务Hessian刘骥讲座--(附源码)

    3. **跨语言支持**:Hessian协议是跨平台和跨语言的,支持Java、C++、Python、PHP等多种编程语言,这使得不同语言开发的服务之间可以无缝交互。 4. **安全机制**:虽然Hessian本身不包含内置的安全机制,但它可以与...

    用Hessian协议实现Android手机与J2EE系统集成的研究.pdf

    Hessian协议支持多种编程语言,如Java、C、C++、C#、.NET、Flash、PHP等,并提供相应的API支持包,便于开发者集成到各自的应用环境中。Hessian协议的特点包括:无需额外模式或接口定义的可序列化类型、自描述性、...

    hessian 在PHP中的使用介绍

    Hessian是语言无关的,这意味着它可以被多种编程环境如Java、PHP等支持。 在PHP中使用Hessian,需要注意以下几点: 1. **安装HessianPHP库**:与SOAP服务不同,PHP并没有内置对Hessian的支持。你需要从第三方源,...

    dubbo-php-framework:适用于Apache Dubbo的php

    适用于Apache Dubbo的php框架 dubbo-php-framework是用于PHP语言的RPC通讯框架。 它与Dubbo协议完全兼容,并且可以同时用作提供商终端和消费者终端。 使用zookeeper进行服务注册发现,并使用fastjson和hessian进行...

    HessianPHP_v2.0.3.zip

    HessianPHP_v2.0.3.zip 是一个用于PHP的开源库,它实现了Hessian二进制协议,允许PHP应用程序与其他支持Hessian协议的语言(如Java、C++或Python)进行高效的数据交换,特别是通过HTTP协议。这个版本,2.0.3,是相...

    PHPHessian 开源源码

    Hessian支持多种数据类型,包括整型、浮点型、字符串、日期、对象以及复杂的数据结构。由于Hessian是二进制的,所以相比XML或JSON,它在传输相同数据量时具有更高的效率和更快的速度。 **JSON-RPC** JSON-RPC是一种...

    php字符集转换

    综上所述,PHP中的iconv函数以及其相关的函数为字符集转换提供了强大的支持。通过理解和应用这些知识点,开发者可以轻松地处理不同编码之间的转换问题,确保程序可以正确显示多语言内容,避免乱码的出现。字符集转换...

    Dubbo开源现状与未来规划.pptx

    - 三方库如Spring、ZK、Hessian等的升级,以满足社区的需求,如REST支持、Spring Boot集成、Hessian对Java 8的支持等。 - Dubbo的核心模块化,旨在提高代码可维护性和扩展性。 - 探索新的运维工具(Ops)如Dubbo ...

    PHP实现的各种中文编码转换类分享

    描述中提到的“主要介绍了PHP实现的各种中文编码转换类分享,本文类库支持简体中文、繁体中文、GB2312、BIG5、UTF-8等多种格式之间的转换”,意味着这个类库提供了丰富的功能,能够方便地在这些编码之间进行转换,...

    liferayPortal

    - Hessian:一种高效的远程过程调用协议。 - Burlap:一种轻量级的RPC框架。 - REST:一种基于HTTP的Web服务架构风格。 - RMI:Java远程方法调用。 - Spring HTTP:基于Spring框架的HTTP客户端和服务端支持。 - WSRP...

    4-6+Apache+Dubbo+Roadmap+2019.pdf

    - 为多种客户端提供了支持,包括Java、JavaScript、Python、Go、PHP、Erlang以及HTTP客户端,方便不同语言环境下的应用集成。 5. 未来发展方向: - 随着微服务架构的普及,Dubbo 将继续加强与Kubernetes等容器...

    Liferay architecture 5

    Liferay Portal支持多种技术,包括AJAX、Apache ServiceMix、ehcache、Groovy、Hibernate、ICEfaces、Java J2EE/JEE、jBPM、JGroups、jQuery JavaScript Framework、Lucene、MuleSource ESB、PHP、Ruby、Seam、...

    resin 入门基础教程.pdf

    - Resin 支持远程过程调用(Remote Procedure Call, RPC),包括 Hessian 等协议,方便不同应用间的通信。 #### 二十一、消息传递 - **HMTP** - HMTP 是 Resin 提供的一个消息传递协议,用于在分布式环境中发送...

    resin-4.0.65-src.tar.gz

    1. **模块结构**:Resin的源码结构清晰,主要包括web容器、JDBC连接池、HTTP服务器、Quercus PHP支持等多个模块。解压`resin-4.0.65-src.tar.gz`后,可以看到`src`目录下有`common`, `server`, `webapp`, `quercus`...

    Hession与Webservice的区别共2页.pdf.zip

    Hession默认支持Java,但也提供了对其他语言的绑定,如Python、PHP等。由于其效率,Hession常用于内部系统间或者对性能要求较高的微服务通信。 接下来是Web服务,通常指的是基于HTTP协议的SOAP(Simple Object ...

Global site tag (gtag.js) - Google Analytics