Thursday, March 08, 2007

Integrating Java and PHP: the Web Services way

Recently on a project, we were faced with the question:
  1. do we put the business logic in the web tier (which was written in PHP 4.7.3) or
  2. do we write the business logic in Java (better tools for development, reliable libraries for some of the tasks we wanted to perform as a part of our business logic, better OO language features than PHP, easy to debug in an IDE, code hidden in class files).
The first option was what we usually call the model 1 architecture, where business logic is written in the same script which serves the presentation code.

In the second approach, we were getting to the point of introducing the MVC pattern to our PHP based web tier by introducing a Java layer to play the model and let PHP scripts be controller and view. This had the added advantage that we could leverage the model written as Java web services in other clients (and we did have other clients than web interface too for our product which provided an alternate interface for user/program to interact with our product and hence we required that the business logic we write for our web interface could be leveraged in other client types too, written in other languages, possibly, which in our case was C/C++). Hence, we opted for the 2nd choice.

We had two options for integrating Java and PHP:
  1. Do it using PHP/Java bridge
  2. Expose the business logic written in Java as web services.
The bridge option is not well supported as of this writing in the PHP world. The Java extension for PHP language is labeled as experimental. So we decided to go with the other option.

Our business logic did not necessitate the use of EJBs (did not require container managed transactions or persistence) for the present, so going the Java path to write our business logic, we wanted to use Tomcat as web container (which could easily be integrated with the Apache web server, running the existing PHP code, using mod_jk(2)).

We developed our web services in Java using the latest JAX-WS 2.1 RI library, primarily because JAX-WS spec makes writing web services in Java pretty easy as compared to the predecessor JAX-RPC 1.1 release (aided by annotations, no more of XML hell). We also made a design choice to use the document/literal style of messaging for maximum flexibility. Here's how a typical JAX-WS code looks:

MyWebServiceImpl.java:

@WebMethod
public MyClassA myWebMethod(
@WebParam(name = "aParam") int aParam) throws MyAppExceptionA, MyAppExceptionB { //.. implementation code }


We chose to use the nusoap 0.7.2 as the PHP web service stack and here's how a typical WS client was written in PHP using nusoap:
client.php:

<?php
require_once('../lib/nusoap.php');

// create a soapclient from wsdl url
$wsdl = 'http://192.168.1.101:8080/MyWebservices/MyWebServiceImpl?wsdl';
$client = new soapclient($wsdl, true);
$err = $client->getError();
if ($err) {
// Display error
}

// specify the soap body content for doc/literal request
$msg = "<web:mywebmethod xmlns:web="\"http://webservice.mycompany.com/\"">
<aparam>3334</aparam>
</web:mywebmethod>";

$namespace = 'http://webservice.mycompany.com/';
$method = 'myWebMethod'; // web method to invoke

$result = $client->call($method, $msg, $namespace, '', false, null, 'document', 'literal');

// Check for a fault
if ($client->fault) {
// Here is how we can do exception handling.
$myAppExceptionA = $result['detail']['MyAppExceptionA'];
if ($myAppExceptionA) {
print "Exception: ". $myAppExceptionA['message'];
}

$myAppExceptionB = $result['detail']['MyAppExceptionB'];
if ($myAppExceptionB) {
print "Exception: ". $myAppExceptionB['message'];
}
} else {
// Check for errors
$err = $client->getError();
if ($err) {
// Display the error - You will not come here in working condition :)
} else {
// Display the result
print_r($result);
// Grab the values in the $result array
}
}
?>

Nusoap stack on PHP end will convert the result in an associative array (as shown in the case of fault handling in the code above). To know the structure of response message to get more clarity on how to extract the data out of result, you can add the following 3 magic debug statements towards the end of the above PHP client code:

echo "<h2>Request</h2><pre>" . htmlspecialchars($client->request, ENT_QUOTES) . "</pre>";
echo "<h2>Response</h2><pre>" . htmlspecialchars($client->response, ENT_QUOTES) . "</pre>";
echo "<h2>Debug</h2><pre>" . htmlspecialchars($client->debug_str, ENT_QUOTES) . "</pre>";

I also used the SoapUI tool (version 1.6) for unit testing my web services and found it to be very useful, especially when we needed to know the exact soap request body content which we needed to embed on the PHP side while invoking the web method. You can do several things with this tools, like generate request templates which you can fill with values to test individual web methods, save such requests and do regression testing later, save the requests to do load testing, view test reports etc.


That's in short about how we can get PHP web tier to invoke methods on a Java web service based business logic tier. I had initially had some trouble in figuring out the way to pass the right arguments to the soapclient() method of nusoap library and after some web searching we could identify how to get it working.

As an aside, this was my first experience of working with PHP language and in my self learning mode i used WAMP distribution (version WAMP5_1.6.5 which includes PHP 5.1.6, Apache 2.0.59, MySQL 5.0.24a and phpmyadmin 2.8.2.4) to quickly setup an environment on my Windows workstation for experiments. I also found the EasyEclipse for PHP (version 1.2.1.1), a very useful IDE for PHP development. And a book i use as reference (only when i need to know how a certain programming thing is done in PHP) is Programming PHP by Kevin Tatroe, Rasmus Lerdorf, and Peter MacIntyre. Its excellent book and has stood by me till date.

The opinion i have formed about PHP till now is that its ideal for a model 1 architecture web application. Its better in such cases than say Servlets/JSP duo because of its simplicity in terms of programming constructs. It simply does not have those advanced features of JSP tag libraries. So for developers who are not fussy about mixing their HTML code with some PHP scripts and have a previous background in Perl or some other such dynamic languages, will be more at ease with PHP than say Java development. Java is object oriented language (a hybrid one though like C++) but PHP is object based (ie PHP has construct for defining classes as Perl but it does not support inheritance, polymorphism etc). So most of the PHP code is more or less procedural, at least thats what is more commonly done (like you are programming in C and creating libraries of functions). Also PHP eases the learning curve as its a dynamic language and does not have standard data types other than arrays (indexed and associative) and scalars. Of course you can define your ADTs but most of the time you will be good working with arrays alone. The arrays in PHP are like a mix of Java's ArrayList and HashMap ie you can use an array as an indexed or associative one. So, in general, i feel if there is a simple web application where all that has to be done is create a catalog out of a database and then allow CRUD using web forms then PHP (and hence model 1 architecture) is suitable, since it gets the work done quicker and resulting code is maintainable. But if you want to support multiple client types (hence model 1 architecture is not what you want) and probably need some advanced middleware services (like persistence, security, transactions) then you are better off with Java EE and other such frameworks.

Share your thoughts by leaving your comments.

3 comments:

Dinh said...

@ On PHP data types
Some data structures are simplified in PHP to give developer flexibility and shorter learning curves. E.x: The autoboxing between string and integer in some cases, array in PHP is the combination between hashmap, array data types. String in PHP sometimes can be understood as an array of characters because developers can access each character by its position. Ex.

$s = 'Hello';
echo $s[1];

It is intentional.

Among PHP's built-in data types, I find resources type is much more abstract and hard to understand and control. The others are so natural to developers so almost people will find that they can be comfortable with PHP in a short time.

@ On SOAP
SOAP is a PHP's built-in language feature so you dont need an external PHP library to get it work: http://php.net/soap Built-in SOAP will lead to much better performance in term of speed and memory.

@ On OOP
You said: "but PHP is object based (ie PHP has construct for defining classes as Perl but it does not support inheritance, polymorphisms etc)."

Feel free to disagree with me but I think that you would want to retake your claim after you have a look at http://www.php.net/manual/en/language.oop5.php

PHP is a dynamic language so it should not go Java way all the time. Method overloading is not good thing to have in PHP.

One of special features in PHP that can be non-existent in other languages is the dual interface. Some APIs do exist both in procedural and OOP interface such as MySQLi, SimpleXML... SPL is another feature that provide a nice OOP interface

In short, PHP's OO model is based on Java but different in some constructs to adapt them with a dynamic and higher level language

@ On JSP comparison
It is hard to compare PHP with JSP because JSP is a framework by nature. Java is a general purpose language that tries to adapt itself with web development. Servlet is a framework (or set of API) built on top of Java to embrace HTTP environment into Java. JSP is built on top of servlet to define a framework that define the way to use a set of custom XML-style tags mixed with HTML that is impossible in Servlet. If you have time to work with PHPTal, Smarty, Blitz which are some of PHP template engines, you will find that they are like JSP-spirit clone in some manners.

@ On Model 1
Model 1 is one of ways to build web application with PHP. I call it page controller. Facebook is an example of page controller-based web application in PHP. However, I love to work with PHP in Model 2 manner. You can find that most of PHP frameworks encourage developers work with Model 2 (or Front controller as it is commonly mentioned in PHP) because it allows them to take advantages of bootstrapping mechanism that is intercepting filter friendly, custom url, advanced routing, better controlled workflow, better interaction with different types of Model (file transfer, database manipulation, webservices..).

@ On middleware services
You said: "and probably need some advanced middleware services (like persistence, security, transactions) then you are better off with Java EE and other such frameworks."

Because the terms "persistence", "security", "transactions" does exist in PHP world so I don't understand what you mean here. Might you mention them in a different light as with PHP. If it is the case, it is a different story. I know in some cases, your application depends on middleware services provided by Java application servers such as Glassfish, your model part should be written in Java or at least in PHP with PHP-Java-bridge extension support. Because my experience with complicated applications in Java is limited, so could you point me cases that "persistence", "security", "transactions" implementation in PHP is impossible or sub-optimized?

Thanks

Anonymous said...

Making gw gold is the old question : Honestly there is no fast way to make lots of GuildWars Gold . Sadly enough a lot of the people that all of a sudden come to with millions of Guild Wars Gold almost overnight probably duped . Although there are a lot of ways to make lots of GuildWars moneyhere I will tell you all of the ways that I know and what I do to make cheap gw gold.

As a new player , you may need some game guides or information to enhance yourself.
habbo credits is one of the hardest theme for every class at the beginning . You must have a good way to manage yourhabbo gold.If yor are a lucky guy ,you can earn so many habbo coins by yourself . But if you are a not , I just find a nice way to get buy habbo gold. If you need , you can buycheap habbo credits at our website . Go to the related page and check the detailed information . Once you have any question , you can connect our customer service at any time .

Farhan said...

Well I Need a plateform which supports both PHP and JSP I have to integrate my site with paymant gateway, that requires JSP to run on the sever so what i need to do, also I am using PHP4 and I think bridge is not supported for this version

Popular micro services patterns

Here are some popular Microservice design patterns that a programmer should know: Service Registry  pattern provides a  central location  fo...