如果您已经成功的运行了教程第二部分的helloworld,一定会感觉到LAJP的使用非常简单,但对于一项新技术做出评价不能只停留在Hello World层面,本节教程将带您更深入地了解LAJP。
PHP和Java都是很优秀的夸平台的编程语言,LAJP在这点上没有限制,凡是能够运行PHP的环境,凡是能够运行Java的环境,就可以运行LAJP。
LAJP有两套传输机制:消息队列和socket,消息队列方式可运行在Unix/Linux/BSD系统,编译PHP时需要加上 --enable-sysvsem,--enable-sysvshm和--enable-sysvmsg 编译选项,使PHP支持信号量、共享内存和消息队列。socket方式对系统平台没有限制,编译PHP最好加上--enable-sockets 编译选项 ,使PHP支持socket。
PHP版本需要高于4.3,这是PHP对使用信号量、共享内存和消息队列的版本要求。
Java环境不需安装任何WEB容器(Tomcat等),LAJP的Java端本身即是带有main方法的,标准的Java应用程序,且全部压缩在唯一的jar文件中,不需要任何的第三方的类库。
JDK版本要求在1.5以上,这是因为LAJP的Java端代码中使用了诸如泛形等语法结构。
windows环境“called to undefined function socket_create” 错误:
在使用socket函数时,经常会报出“called to undefined function socket_create”,在网上搜一下发现此错误非常频繁(PHP不认为这是个bug),当遇到这个错误时,请按下列步骤解决:
尝试运行:<?php var_dump(extension_loaded("sockets")); ?> 如果输出false,是php_sockets.dll没有加载。
1. 检查php.ini,确保extension=php_sockets.dll前没有";"。
2. 检查httpd.conf有下面几行:
# c:/PHP/是php的安装路径(PHPzip解压方式安装)
LoadModule php5_module c:/PHP/php5apache2_2.dll
# 按模块模式加载
PHPIniDir "c:/PHP/"
AddType application/x-httpd-php .php
# 按CGI模式加载, c:/php/是php的安装目录
#ScriptAlias /php/ "c:/php/"
#AddType application/x-httpd-php .php
#Action application/x-httpd-php "/php/php-cgi.exe"
3. 检查php目录下有没有php_sockets.dll文件,如果没有从ext目录中copy过来,php5默认搜索路径在php,而不是php/ext。
4. 尝试以命令行方式运行,如果命令行可以,将php.ini复制到c:\windows。
//命令行方式运行, php.exe和php.ini在php安装目录下
php.exe -c php.ini <路径>\php文件
PHP通过lajp_call()函数调用Java端方法,函数的第一个参数格式为:"类名::方法名",从第二个参数起是向Java方法传参。
例如Java端:
001 package aaa.bbb.ccc
002 public class MyClass
003 {
004 public static final int myMethod(int a, int b)
005 {
006 return a + b;
007 }
008 }
PHP的调用方式:
001 <?php
002 $c = lajp_call("aaa.bbb.ccc.MyClass::myMethod", 10, 20);
003 ?>
Java服务方法必须声明为public static final
,在LAJP设计中Java端服务方法是无状态的,强制声明static表明了这个态度;强制声明final是LAJP的另一个设计理念:简单、直白,不希望被封装为“反转控制”等复杂模式,这点和PHP一贯的简约风格相一致。
php语言规范定义了8中数据类型:boolean、int、float、string、array、object、resource、 NULL;java语言的数据类型分为2类:基本数据类型和对象类型,基本数据类型有byte、short、int、long、 char、boolean、float、double, 对象类型包括数组、集合、javaBean等。在LAJP架构中,php数据以参数形式传递给Java方法,Java方法的返回值再回传给php调用程序,在调用过程中,php数据“自动”转换为Java数据,反之亦然。
并不是所有数据类型都可以转换,在LAJP中建立了以下转换规则:
php | java | 说明 | |
布尔 | boolean | boolean | |
整形 | int | int | |
浮点 | float | double | 在php中float和double含义相同 |
字符串 | string | java.lang.String | |
顺序集合 | array(key:int ) | java.util.List | php中array的每个元素的key类型必须是int |
key-value集合 | array(key:string ) | java.util.Map | php中array的每个元素的key类型必须是string |
对象 | object | JavaBean | |
空 | NULL | null |
需要说明的是PHP中的array、object和Java数据类型的转换。
array:
在PHP中,array可以描述多种结构: 顺序集合(类似Java的ArrayList),key-value集合(类似Java的Hashtable或HashMap),栈等。在LAJP中只能使用两种结构:
1. 顺序集合 集合元素的key类型为int类型。
$a = array();
$a[0] = 10;
$a[1] = 20;
$a[2] = 30;
// 也可以:
$a = array();
$a[] = 10;
$a[] = 20;
$a[] = 30;
//但不能
$a = array();
$a['A'] = 20;
$a[1] = 10;
$a[2] = 30;
2. key-value集合 集合元素的key类型为string类型。
$a = array();
$a["a"] = 10;
$a["b"] = 20;
$a["c"] = 30;
在PHP的array转换为Java时,LAJP内部是通过查看array的第一个元素的key,如果key是int类型,被转换为java.util.ArrayList;如果key是string类型,被转换为java.util.HashMap,反过来也一样,Java的List转换为PHP的以KEY为int的数组,Map转换为PHP的以KEY为String的数组。
在PHP的array中的元素,可以是表1中的任何一种类型,包括array和Object,这意味着可以构建出复杂的结构,如数组中的数组(通常称为二维或多维数组)。
object:
PHP对象被映射到Jave的JavaBean对象,这意味着PHP类中的每一个属性,在Java对应类中都有一个同名,同类型(符合表1映射关系)的属性,且此属性有getter和setter方法。
目前只支持PHP4规范对象转换到Java,这是因为在LAJP内部转换时需要将PHP对象数据序列化,PHP5对象不能转换,这点尤其要注意。
目前也不支持PHP中的命名空间(Namespaces),在PHP中用"_"表示Java中的".",如要映射到Java的"com.foo.MyClass"类,需要在PHP中定义类"com_foo_MyClass"。
在LAJP中提供了一个小工具,将Java的JavaBean类自翻译为对应的PHP类,例如在Java中有这样的一个JavaBean:
001 package cn.com.aili;
002 public class PhpObject
003 {
004 private int a;
005 private double b;
006 private boolean c;
007 private String d;
008
009 ...getter和setter方法
010 }
编写一个PHP文件:
001 <?php
002 require_once("../lajp/php_java.php");
003 $ret = lajp_call("lajp.ReflectUtil::javaBean2Php", "cn.com.aili.PhpObject");
004 echo "{$ret}";
005 ?>
运行后,会在页面输出对应的PHP类:
cn_com_aili_PhpObject
{
var $a;
var $b;
var $c;
var $d;
}
在LAJP体系中,PHP充当客户端(调用者),Java充当服务端(服务提供者)。
* PHP
负责和浏览器客户端的交互,编写HTML页面、表单,接收浏览器提交的数据,对提交数据的合法性交验,Cookie/Session的维护,Ajax服务等是其固有的职责。PHP不应该编写复杂业务逻辑程序,不应出现连接接数据库相关代码。
* Java
负责编写业务逻辑,数据对象,数据库程序。在Java中不应该出现和浏览器交互的代码,例如不能出现Servlet/JSP API代码,不应编写Ajax服务。
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛