借《淺談PHP與Java之Web開發整合技術》说LAJP

这是早先在网上流传的一篇PHP与Java相结合的技术文章,其中列举了三种整合技术:SOAP、 Quercus、PHP/Java Bridge,这对理解并使用LAJP框架有很好的参考作用,因此将原文摘录在此,并在后面作出我个人的评价。


========================================

《淺談PHP與Java之Web開發整合技術》

作者:鄭哲聖 摘录来源:http://newsletter.ascc.sinica.edu.tw/news/read_news.php?nid=1483

前言

PHP為語法簡單的腳本語言,可以做為HTML的嵌入型語言,而且與Apache網頁伺服器搭配的設定容易、效能亦高。Java則是商業用途的優秀 物件導向語言,具有非常多有用的程式庫,也有許多Web應用程式開發框架(framework)。比較PHP與Java,PHP的商業用途程式庫較為缺 乏,而Java的語法、開發環境設定較為複雜。因此,Web開發人員不應對 PHP或Java抱持成見,而應審時度勢,結合PHP與Java各自的優勢,才能更有效率地開發Web應用程式。本文將介紹三種不同的PHP與Java整 合開發技術,希望可以提供建置PHP與Java之Web開發整合環境的參考。

三種PHP與Java之Web開發整合技術

目前已知的PHP與Java之Web開發整合技術可分成SOAP(Simple Object Access Protocol)、Quercus、PHP/Java Bridge三種,這些技術可以讓PHP與Java在開發Web應用程式時互相使用彼此的程式庫。本文因篇幅關係,將側重於介紹如何在PHP程式中使用 Java程式庫以及如何配置SOAP、Querus與PHP/Java Bridge等套件。

本文使用的Java程式庫範例如List-1所示:

List-1 HelloService.java

下面將介紹如何讓PHP結合SOAP、Querus與PHP/Java Bridge技術,呼叫echoHello(”Jason”),並得到”Java say hello to Jason”的執行結果。

一、SOAP(Simple Object Access Protocol)

SOAP是IBM及 Microsoft等公司開發、W3C推薦,用來實作分散式物件技術的協定。SOAP提供一套以XML來包裝程式呼叫、參數傳遞與訊息回傳的機制,藉由 XML純文字的特性,可透過HTTP、HTTPS、SMTP等通信管道穿越企業的防火牆,比起CORBA、Java RMI及DCOM這些以專屬binary格式傳送資料的分散式物件技術協定,SOAP具有與程式語言、平台和硬體無關的特性。

Java語言最常使用的SOAP套件是Apache Axis2,PHP的是php-soap延伸模組。下面說明如何透過這兩個SOAP套件整合PHP與Java。

(一) 前置作業:安裝PHP >=5.0版、JDK >=1.4版以及Tomcat。

(二) 使用Apache Axis2將List-1 HelloService.java程式庫部署成SOAP的Web Services

1. 安裝Apache Axis2

首先到Apache Axis2網站首頁下載最新的WAR(Web Archive)Distribution-axis2.war。將Tomcat的伺服器配置中的unpackWARs設為True,然後將 axis2.war複製到Tomcat的webapps目錄下。重新啟動Tomcat,如果訪問http://localhost:port/axis2 可以看到Axis2歡迎頁,即完成Apache Axis2的安裝。其中port是Tomcat的網路服務埠口,一般為8080。

2. 部署HelloService服務

(1) 撰寫services.xml來描述服務部署訊息

HelloService.java的服務部署訊息如List-2所示。服務的name屬性定義服務的名稱。Apache Axis2使用服務的名稱創建服務的端點位址,如http://localhost:port/axis2/services/。 因此,HelloService服務的端點位址為http://localhost:port/axis2/services /HelloService。 ServiceClass參數指定服務對應的類別。每個元素定義服務中一個操作的配置。的 name屬性應設置為服務對應類別中方法的名稱。messageReceiver元素定義用於處理此操作的消息接收器。

List-2 services.xml

(2) 將服務包裝成Axis Archive

Apache Axis2服務必須先包裝成Axis Archive (.aar)才能部署。Axis Archive (.aar)的格式與jar文件相同(使用jar或zip創建),內部包含服務對應的類別與services.xml。HelloService服務的 aar文件內部結構如List-3所示:

List-3 HelloService.aar的內部結構

(3) 完成服務部署

在Apache Axis2中部署服務相當簡單,只需將 .aar複製到Tomcat目錄下的/webapps/axis2/WEB-INF/services/即可完成部署。

(三) 使用php-soap延伸模組讓PHP調用HelloService服務

1. 載入、設定php-soap延伸模組

(1) 載入php-soap延伸模組

在php.ini找到延伸模組設置部分,增加一行代碼來自動載入php-soap延伸模組。在Windows上,這一行代碼是: 「extension = php_soap.dll」;在UNIX上是:「extension = php_soap.so」。定義、設定extension_dir,讓它指向包含php-soap延伸模組的目錄。如果需要重新編譯原始程式碼,請在 configure命令中添加–enable-soap選項,再重新編譯。

(2) 設定php-soap延伸模組

在php.ini增加下列代碼,以完成php-soap延伸模組的設定:

[soap]
soap.wsdl_cache_enabled=0
soap.wsdl_cache_dir=”/tmp”
soap.wsdl_cache_ttl=86400

2. 撰寫PHP的SOAP client

程式如List-4所示,sayHello1.php首先會讀取HelloService服務的WSDL文件(由Apache Axis2根據services.xml產生)來創建SOAP client,再設定參數param0為Jason,然後呼叫HelloService服務的echoHello函式,最後得到並列印出回傳的結 果:”Java say hello to Jason”,詳細的運作過程如【圖1】所示。

List-4 sayHello1.php

【圖1】利用SOAP整合PHP與Java之運作示意圖

二、Quercus

Quercus是Caucho Technology公司為resin application server開發之100%以Java實作的PHP 5引擎(required JDK 1.5)。Quercus可以讓PHP程式在JVM上執行,下面介紹如何使用Quercus搭配resin來整合PHP與Java。

(一) 前置作業:安裝JDK >=1.5版。

(二) 安裝resin application server及Quercus

首先到Caucho Technology公司的首頁(http://www.caucho.com/)下載resin application server的zip文件(內含Quercus),然後將其解壓縮到某個目錄$RESIN_HOME,例如:windows環境下的c:\resin。啟 動$RESIN_HOME下的httpd.exe,使用瀏覽器連接http://localhost:8080/,如果可以看到成功執行的畫面,代表 resin application server及Quercus已成功安裝。

(三) 將List-1 HelloService.java放在$RESIN_HOME/webapps/ROOT/WEB-INF/classes/hello/目錄下。 HelloService.java在被調用時,會自動被編譯成class文件。

(四) 撰寫PHP調用HelloService.java的程式,如List-5所示。將sayHello2.php放 在$RESIN_HOME/webapps/ROOT/ 目錄下。

List-5 sayHello2.php

(五) 使用瀏覽器連接http://localhost:8080/sayHello2.php,resin application server就會把$RESIN_HOME/webapps/ROOT/sayHello2.php送給Quercus轉換成相對應的java程式,然後 編譯、執行,最後resin application server回傳”Java say hello to Jason”,顯示在瀏覽器畫面。

使用Quercus搭配resin整合PHP與Java只需要安裝JDK、resin application server(內含Quercus),若要連接資料庫才需再安裝其他資料庫伺服器,如:MySQL Server,環境的設置比起SOAP與PHP/Java Bridge整合方式來得簡單。但Quercus與PHP/Zend Engine會有相容性的問題。

三、PHP/Java Bridge

Java和script語言的介面定義於JSR 223,JSR是Java Specification Requests的簡寫。JSR 223規定了從script語言建立Java類別實體、呼叫方法以及取得結果物件的介面,也規定了從Java呼叫script語言的方法、轉換參數以及傳 回值的方法。下面介紹如何使用PHP/Java Bridge套件讓PHP使用Java程式庫,PHP/Java Bridge是JSR 223之PHP 5的Java介面實作。

(一) 前置作業:安裝PHP >=5.0版、JDK >=1.4.2版、Apache HTTP Server >=2.0版、Tomcat(使用port 8080)。

(二) 安裝PHP/Java Bridge套件

1. 首先到PHP/Java Bridge網站的首頁(http://php-java-bridge.sourceforge.net/doc/),點選「download」可以連 到SourceForge.net,選擇下載php-java-bridge_j2ee.zip文件,解壓縮後,可以取得 JavaBridge.war文件。將Tomcat的伺服器配置中的unpackWARs設為True,然後將JavaBridge.war複製到 Tomcat的webapps目錄下。重新啟動 Tomcat,即可在webapps目錄下看到JavaBridge這個目錄。

2. 將JavaBridge目錄下的java子目錄完整複製到$PHP_INCLUDE目錄,並將$PHP_INCLUDE目錄加到 php.ini的include_path。例如:若$PHP_INCLUDE是c:\php5\pear,則include_path=”.;c: \php5\pear”。java子目錄內包含使用PHP實作的PHP/Java Bridge原始程式碼。

(三) 將List-1的程式放在Tomcat目錄下的webapps/JavaBridge/WEB-INF/classes/hello/ 中,並編譯之。

(四) 撰寫PHP調用HelloService.java的程式,如List-6所示。將sayHello3.php放在Apache Server的DocumentRoot目錄下。

List-6 sayHello3.php

(五) 使用瀏覽器連接http://localhost/sayHello3.php,則Apache Server會將sayHello3.php交給PHP/Zend Engine編譯、執行。當PHP呼叫Java程式庫時,PHP/Java Bridge (java子目錄下的php程式)會將此呼叫轉換成 *.phpjavabridge文件格式,然後傳送到Tomcat下JavaBridge的 php.java.servlet.PhpJavaServlet處理,最後透過PHP/Java Bridge回傳結果給PHP。List-6程式執行後可看到”Java say hello to Jason”顯示在瀏覽器畫面。

結語

隨著Web的發展,使用單一語言來開發Web應用程式未必是最有效率的方式。期許透過本文的介紹,可以讓Web開發人員瞭解如何使用PHP與 Java兩種語言整合開發Web程式的技巧,更希望可以促使Web開發人員思考、發掘更好的Web 應用程式開發方式,以因應電子化時代快速變動及大量產生的資訊需求。

參考資料

【1 】SOAP – Wikipedia, the free encyclopedia. Available at URL
http://en.wikipedia.org/wiki/SOAP

【2 】Apache Axis2. Available at URL http://ws.apache.org/axis2/

【3 】Quercus: PHP in Java. Available at URL
http://www.caucho.com/resin-3.0/quercus/

【4 】PHP/Java Bridge. Available at URL http://php-java-bridge.sourceforge.net/doc/

【5 】JSR 223: Scripting for the JavaTM Platform. Available at URL
http://jcp.org/en/jsr/detail?id=223

[原文完]

========================================

评:

文中列举了三种整合技术:SOAP、Quercus、PHP/Java Bridge,这里来一一分析其特点。

【SOAP 】

SOAP是WebService中的对象传输协议,是当前我们首先会想到的跨语言、跨平台的传输技术,在过去则是CORBA。CORBA是已经飘过 去的云,无需多说,这里主要说说SOAP的特点:

主要优点:轻量级相对简单,HTTP协议穿透能力强,当前非常流行。
主要缺点是慢。

这几年我们在为电信开发项目,系统与系统间传输主要使用了三种技术:Tuxedo、EJB、WebService,从传输效率上比较,最快的是 Tuxedo,最慢的是WebService(SOAP)。Tuxedo在计费等及其要求运行速度的系统中有其他技术不能替代的优势,但Tuxedo编程 使用C语言,运用面不广;电信系统整体以J2EE为主,核心的数据传输使用EJB,而EJB的主要问题是系统间依赖性太强,在电信以大大小小数十个系统组 成的大系统中,解耦尤其重要。实践中EJB经常造成的问题是当其中一个系统升级,会造成和周边系统版本不一致。后来外围系统多用WebService目的 就是减少系统间的耦合性,但带来的另一个问题是传输效率慢了很多,主要原因有两点:数据用XML封装体积大,DOM解析内存占用多。

回过头来看LAJP,传输效率上应比Tuxedo还要好,因为Tuxedo再快也是基于网络的,而LAJP是基于消息队列,当然这只是理论对比、纸 上谈兵,具体影响效能的因素很多,我以前写过一篇文章《Linux下消息队列和socket绝对速度 比拼》,对研究消息队列的性能有一点参考。

从简单性上看,LAJP比WebService简单,Axis配置有一定的复杂性,且WSDL、SOAP等概念性太强,初学者难以领会。

【Quercus 】

Quercus是走错了方向的技术,这是Java“通吃天下”思想的产物,没了Apache的帮衬,没了原生函数库的支持,PHP还剩下什么?没毛 的凤凰连原始的asp都不如。

【PHP/Java Bridge 】

我对php-java-bridge了解不深,初看和我的LAJP有些相似(应该说LAJP和php-java-bridge相似,毕竟是LAJP 出道晚),以我目前的了解它欠缺PHP和Java的数据映射,使用起来不方便,另外结构上复杂了一些。

站在LAJP的立场上,我对原文中三种技术或多或少的给予批评,但文中的观点却极为赞成:“Web開發人員不應對 PHP或Java抱持成見,而應審時度勢,結合PHP與Java各自的優勢,才能更有效率地開發Web應用程式”。这是具有大局观、大境界的观 点,看似简单,实则深奥。在创建LAJP这个开源项目时,我预想了可能遇到的阻力:

1. 从结构上看LAJP和JSP+JavaBean是一样的,既然已有JSP+JavaBean,为什么还要LAJP?
2. 我是Java程序员,LAJP要求学习PHP,不愿意,有困难。
3. LAJP是个人负责的开源软件,技术上有风险。

1. 不考虑底层实现,从架构上看,LAJP和JSP+JavaBean确实是一样的,我们可以换个角度看这个问题,如果用纯JSP和PHP开发Web系统,熟 优?LAJP可以看作是JSP+JavaBean变换成PHP+Javabean,所谓取之长,补之短,道理就在这里。

2. Java程序员看不起、不愿学PHP,这是对PHP有成见,一直以来都有PHP、asp程序员水平不高的错误观点。实际上现在流行的开源Web软 件,PHP质量明显高于Java,像wordpress,phpBB等软件,还没有Java开发出能望其项背者。而且PHP相当易学,对一个从事过Web 开发的Java程序员,PHP的学习难度远小于Struts、Spring,PHP号称5分钟上手,资质差的一小时上手,两星期熟练不会成问题,况且 PHP原生函数会带给你操作系统、图像编辑等新的领域的知识,也不会让你为一个上传组件七寻八找一堆jar文件,何乐而不为?

3. 虽然我自己很有信心,但未经过长时间、大应用的考验,LAJP能否作为一个稳定可靠的架构组件是有疑问的,这里我讲述LAJP中使用的技术,大家可以从中 分析一下:

先说PHP端,在这里LAJP没有要求添加.so,只添加了一个php_java.php文件,在这个文件里运用了三项技术:PHP序列 化,System V的消息队列和System V的信号量。序列化是PHP语言的核心,System V在Unix中已存在了超过20年,所以这里没有要担心的。

LAJP的主要实现在Java端,大部分代码在做PHP序列化数据的解析和组装,基本都是枯燥的字符串拼接操作,这里可能有小bug,但不会有硬 伤;其次,运用了Java的反射机制来查找类、方法,并调用执行方法,这些和Struts、Spring的实现是相似的(JDK中就提供了那几个反射操 作),也不大会出问题;再有,通过JNI操作System V的信号量、消息队列,JNI是比较容易出状况的地方,但我认为也不大可能出现问题,因为实现代码太过简单了。

最后,也是我在LAJP上思考最多,至今没有更好的改进思路的地方在于多线程服务。在LAJP中PHP可看作是客户端,Java可看作服务端,当 PHP发起一个服务调用时,Java必须应对一个服务线程,这称之为并发服务,Tomcat、Websphere的服务也是这样的。从稳定性上讲,并发线 程相对于并发进程要差很多。在设计服务线程时,超时问题是不能回避的,但在多线程服务中,没有完美的停止一个服务线程的方法,这不是Java放弃了线程 stop()方法造成的原因,而是多线程本身的机制。而Java的JVM机制,无法做成多进程并行机制(太耗内存),这也是Tomcat相比Apache 不稳定的重要因素之一。相对于使用Tomcat、Websphere这些纯Java的服务,LAJP理论上要稳定一些,因为最可能出状况的HTTP服务这 一块交给了Apache,而LAJP中Java服务超时的几率要小很多。

參考資料

【1 】线程相关的资料可阅读《UNIX环境高级编程》第11章“线程”和第十二章“线程控制”,在这里不建议阅读Java的书籍,因为Java线程“丢失”了 太多的细节。

【2 】System V 消息队列、信号量资料可阅读《UNIX网络编程(第二卷)进程间通讯》。对于System V不利的小道消息是这项技术老得连最初作者是谁都搞不太清,现在更是没人来维护,有利的消息是有大量的服务长期在运用着它,例如Oracle。

你可能感兴趣的:(借《淺談PHP與Java之Web開發整合技術》说LAJP)