php与java通信

PHP和Java各自有着鲜明的特点:
PHP简单、易学,开发动态网页效率高,草根文化气息浓重,是语言世界的平民英雄。
Java强大而复杂,有众多高端功能,又有IMB、Oracle等企业大颚的追捧,是语言世界的贵族王子。
不管是平民英雄还是贵族王子,都不满足在各自领域称王,于是平民英雄祭出LAMP大旗,在PHP5新的对象模型帮衬下,硬要往上层阶层闯一闯,无奈 金融、电信等王侯们不大欢迎;而贵族王子也非常重视WEB这个广大的基层社会,先制定Servlet/JSP法令,跟着又推出struts、JSF、 Taglib、JSTL、Spring等系列政策,试图消除阶级等级概念,但实施手法贵族气太浓无法深得民心。平民就是平民,贵族就是贵族,硬要将自己也 视为对方阵营里的一员,只有一个结果:牵强。
PHP结合Java是早已有的想法,PHP负责WEB层,Java负责业务和数据逻辑层,真是一对黄金组合。但PHP和Java是两个不同的语言, 如何将他们结合在一起是个问题。实际上已经有了一些手段:如PHP中内置了调用Java的方法,开源的也有php-java-bridge,这里介绍的一 个新的解决思路。
从操作系统层面观察: PHP和Java是系统中运行的不同进程,他们之间沟通属于进程间通信技术(IPC):
php与java通信 - lijianwei_123 - lijianwei_123的博客
在传统的Unix环境中,IPC技术有:管道、消息队列、共享内存、信号量等,在当今TCP/IP流行的大背景下,IPC已经鲜有耳闻了,但在同一 个系统中,IPC通信比基于TCP的socket通信在性能、资源占用方面有相当大的优势,所以今天我们重新挖掘IPC这门传统工艺,让它还发出新的光 芒。
本文介绍的思路即是使用IPC技术来结合PHP和Java。
在Unix/Linux中,PHP基本提供了所有IPC的访问接口,这点不难想象,因为PHP可以看作是以C语言为核心的一个壳,而IPC是系统内 核的组成部分,对外提供了一组C函数接口,因此PHP可以非常顺畅的运用IPC技术。而Java没那么幸运,为了追求夸平台性(Windows的IPC技 术和Unix的不同),没有提供系统级的IPC访问,这也体现了Java的文化特色:为追求统一可牺牲效能。
好在Java有和C对接的JNI接口,可利用它来实现我们的设想,最后的思路如下图:
php与java通信 - lijianwei_123 - lijianwei_123的博客
从上图中看出,PHP承担HTTP层的职责,而Java承担业务层的职责,他们通过System V Message Queue(消息队列,进程间通讯IPC中的一种)相互沟通,Java需要JNI的支持。
通信问题解决了,下来就需要考虑通信内容的问题了。PHP和Java各有其语言内部定义的数据类型,当PHP数据传送到Java,或Java数据传 送到PHP时,怎样进行转换呢? 很多人马上会想到使用xml,xml确是一种夸平台、能够很好描述对象模型的数据封装技术,但xml体积大传输速率慢,通讯两端解析也比较麻烦。
实际上,无论是PHP还是Java,在语言设计时都考虑了数据怎样传输和存储的问题,那就是序列化,例如EJB调用就是通过Java的序列化对象来 传输数据的。
PHP的序列化非常巧妙,例如:
整形: $i = 5 序列化后是 i:5
字符串: $s = “abcd” 序列化后是 s:4:”abcd”
数组:$arr = array(”a” => “value1″, “b” => “value2″) 序列化后是 a:2:{s:1:”a”;s:6:”value1″;s:1:”b”;s:6:”value2″;}
对象: class aaa{var $attr1 = 5; var $attr2 = “ABCD”;} 序列化后是 O:3:”aaa”:2:{s:5:”attr1″;i:5;s:5:”attr2″;s:4:”ABCD”;}
简单而明了,不仅描述了数据结构,并带有数据原来的类型,问题得以解决。使用PHP序列化数据作为PHP和Java的通讯数据格式,不仅效能高,而 且更加接近语言本意。
开源项目LAJP 就是以上述思想为核心的实现技术,使用起来也非常简单,下面是一个示例程序:
php端程序
  1.  
  2. <?php
  3.   require_once("../lajp/php_java.php"); //LAJP提供的程序脚本
  4.  
  5.   //php类,映射到JavaBean 类:cn.com.ail.test.Bean
  6.   class cn_com_ail_test_Bean
  7.   {
  8.     var $a = "v1";
  9.     var $b = "v2";
  10.   }
  11.  
  12.   $p1 = "a";
  13.  
  14.   $p2 = array(); //数组有两 个元素,没有规定数组下标(默认下标是int类型0和1),映射到java的java.util.List类型
  15.   $p2[] = 10;
  16.   $p2[] = 20;
  17.  
  18.   $p3 = new cn_com_ail_test_Bean;
  19.  
  20.   //调用java服务
  21.   //lajp_call是“php_java.php”脚本提供的函数
  22.   //参数 cn.com.ail.test.Objtest::method1表示调用java的cn.com.ail.test.Objtest类中的 method1方法
  23.   //后面的$p1,$p2,$p3是向method1方法传递的参数。
  24.   $ret = lajp_call("cn.com.ail.test.Objtest::method1", $p1, $p2, $p3);
  25.  
  26.   echo "返回信息:".$ret;    //打印"OK,收到并返回字符串应答"
  27. ?>
  28.  
java端程序
  1.  
  2.   //对应php中$p3的JavaBean
  3.   package cn.com.ail.test;
  4.   public class Bean
  5.   {
  6.     private String a;
  7.     private String b;
  8.        
  9.     public String getA()
  10.     {
  11.       return a;
  12.     }
  13.     public void setA(String a)
  14.     {
  15.       this.a = a;
  16.     }
  17.     public String getB()
  18.     {
  19.       return b;
  20.     }
  21.     public void setB(String b)
  22.     {
  23.       this.b = b;
  24.     }
  25.   }
  26.  
  27.   //java端服务
  28.  
  29.   package cn.com.ail.test;
  30.   public class Objtest
  31.   {
  32.     //服务方法,只是简单的打印入参并返回简单字符串
  33.     public static final String method1(String param1, java.util.List param2, Bean param3)
  34.     {
  35.       System.out.println("$p1=" + param1);
  36.       for (int i = 0; i < param2.size(); i++)
  37.       {
  38.         System.out.printf("$p2[%i]=%i\n", i, (Integer)param2.get(i));
  39.       }
  40.       System.out.println("$p3->a=" + param3.getA());
  41.       System.out.println("$p3->b=" + param3.getB());
  42.  
  43.       //返回
  44.       return "OK, 收到并返回字符串应答";
  45.     }
  46.   }
  47.  
LAJP的相关资料,可查看其网站:http://code.google.com/p/lajp/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值