
Recently on a project, we were faced with the question:
- do we put the business logic in the web tier (which was written in PHP 4.7.3) or
- 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:
- Do it using PHP/Java bridge
- 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.