Articles
Enterprise Architecture
by Gary Horen
02/13/2007
PHP is a very popular scripting language. BEA WebLogic Server, on the other hand, is an application server built for Java. How can you run both of these technologies side by side and reap the benefits from both the worlds of PHP and Java? Well, a PHP-Java bridge is one approach, and this tutorial is a cookbook for setting up and using two different bridge offerings that allow PHP and Java application code to work together.
The available implementations of the PHP engine (the core interpreter that provides support for the PHP language) that work with WebLogic Server are native code. An instance of the engine runs in its own operating-system process and must somehow communicate with other processes involved in a Web application—for example, with a Web server or a Java application server. In the case of a Java server, technology is available that makes the communication fairly transparent to an application programmer. There is a component that does the work of marshaling data back and forth between the two environments and that offers PHP language constructs an application developer can use to integrate the two languages. This component is the PHP-Java bridge.
The encompassing example that motivates all the others is to be able to blend Java and PHP in the same application. Here are some ways in which this can be done:
The first two cases are illustrated below. The third is left for a future discussion.
Two bridges are available at present, and both can be used with WebLogic Server. One is a commercial product available from Zend Technologies Ltd. The other is an open-source component, licensed under LGPL, housed on SourceForge. (A third implementation exists, at php.net, but that one is defunct; it doesn't support the latest version of PHP, and will not be discussed in this tutorial.)
Both bridges permit PHP to talk both to Plain Old Java Objects (POJOs) and to Java EE resources that live on WebLogic Server. You get to WebLogic Server resources in the way you would expect: through JNDI. The following code sample shows PHP code that will obtain a resource that lives on WebLogic Server—for example, an EJB, a database connection, or JMS Queue. This code works with both bridges:
// Get a reference to a container-managed resource from WebLogic Server
function getWebLogicResource($jndiName) {
// Set WebLogic-specific parameters for creation of jndi naming context:
// (weblogic.jar must be on the PHP-Java Bridge classpath)
$envt = array(
"java.naming.factory.initial" => "weblogic.jndi.WLInitialContextFactory",
"java.naming.provider.url" => "t3://localhost:7001" // replace with your target server URL
);
// The bridge creates the naming context object in the local JVM.
$ctx = new Java('javax.naming.InitialContext', $envt);
// Now JNDI crosses the network, to obtain the resource.
return $ctx->lookup($jndiName);
}
If you work through this tutorial with a real implementation, don't try to test both bridges on the same machine at the same time. The Zend product puts things on the execution search path and starts services, which interfere with the operation of the SourceForge bridge.
If you need help, post questions and comments to the Dev2Dev PHP newsgroup. The testing for this tutorial was done on Windows XP. Both these bridges work on a variety of Windows and Unix platforms; check the documentation for the corresponding offering to see if it supports the configuration you have in mind.
Zend supplies the engine that provides the vast majority of PHP support to customers today. The core engine is open source, but the bridge component that Zend offers is part of a commercial product, called Zend Platform. The Zend Platform Java Bridge is described here.
To use this bridge, you must install the Apache Foundation's HTTP Server (or, on Windows, you can use Microsoft's IIS). Complete installation instructions come in the Zend Platform Installation Guide, distributed with the Zend Platform product.
The runtime configuration is described in Figure 1. The bridge instantiates a JVM, to which it passes requests to instantiate and manipulate Java objects, including those delivered through JNDI.
Figure 1. Running a Java bridge with Apache as the Web server
In this configuration:
Helpful hints:
All .jar files that are used by the bridge must appear on the environment classpath. This bridge does not have a classpath configuration option.
This bridge does not convert data dynamically like the core PHP engine does. You must do type conversion in your PHP code. For example, if you call a Java method that looks like this:
public void doSomething(int i);
with this PHP code:
$var = "1" $javaObject->doSomething($var);
the Zend bridge will throw an exception complaining that the input parameter is of the wrong type. Since the bridge doesn't do implicit conversion, you can force the interpreter to do the conversion from a string to a numeric value before it passes the parameter in with:
$javaObject->doSomething($var + 0);
This is a free, open-source offering that wraps the Zend core engine. You can configure it to operate in the same way as the Zend Platform bridge shown above (that is, as a connection between an Apache/PHP configuration and a Java EE Server). This bridge also works in an additional configuration: It can be deployed as a Java servlet, as shown in Figure 2.
To install the SourceForge Java Bridge:
Figure 2. Running SourceForge Java Bridge as a PHP servlet
In this configuration:
Helpful hints:
We have provided a sample EJB and a PHP client program that will use the bridge functionality. This code will run with both bridges. The download contains a PHP script, the EAR containing the Trader EJB, and the client jar. (The EAR file also contains source code for all the Java types.) To run the example:
You can see the source code for ejbref.php in this code sample. It loads a form, and when the user posts a request back, it instantiates the EJB on WebLogic Server in the same way as the first code sample in this article.
<html><head><title>Buy or Sell shares</title></head>
<body>
<?php
if (isSet($_POST['ticker'])) {
$trader = getBean();
if (isSet($_POST['buy'])) {
$result = $trader->buy($_POST['ticker'], ($_POST['shares'] + 0) );
$action = 'bought';
}
else {
$result = $trader->sell($_POST['ticker'], $_POST['shares'] + 0);
$action = 'sold';
}
$trader->remove();
print <<<__HTML__
<i>{$result->getNumberTraded()} shares of {$result->getStockSymbol()} $action.</i>
__HTML__;
}
else {
print <<<__HTML__
<form action="http://localhost:7001/JavaBridge/ejbref.php" method="post">
Ticker Symbol: <input type="text" size="4" name="ticker"/><p>
Number of Shares: <input type="text" size="6" name="shares"/><p>
<input type="submit" name="buy" value="buy"/> <input type="submit" name="sell" value="sell"/>
__HTML__;
}
function getBean() {
$envt = array(
"java.naming.factory.initial" => "weblogic.jndi.WLInitialContextFactory",
"java.naming.provider.url" => "t3://localhost:7001"
);
$ctx = new Java('javax.naming.InitialContext', $envt);
$home = $ctx->lookup('TraderHome');
return $home->create();
}
?>
</body>
</html>
Two available tooling options are Zend Studio, a commercial product, and the Eclipse PHP Development Tools (PDT). You can download a stable version of the Eclipse PDT from the Zend Eclipse update site: http://www.zend.com/pdt. (Later versions are available directly from the Eclipse PDT Project.) The PDT may be installed on Workshop Studio release 3.2 or later (but not yet in Workshop for WebLogic). The PDT gives you PHP editing tools (code coloring, auto completion, syntax error detection), and Workshop Studio will help you to deploy the SourceForge PHP Servlet configuration to WebLogic Server.
The Zend Studio debugger (a commercial product) works well with the Zend Platform bridge. The version of the PHP core engine distributed with the SourceForge Bridge does not appear to have the server-side debugger installed, so it will not work out of the box with Zend Studio. At this point, the Eclipse debugger is still a work in progress. As of this writing we have not been able to get it to work with either bridge.
This tutorial provides instructions for setting up PHP-Java bridges. It also provides ample evidence of the complexity involved in creating and managing such a configuration. We remain interested in pursuing an integration between PHP and Java that is colocated on the JVM, which we believe will make life easier for developers interested in blending the two languages in their applications. See my blog about our possible future plans.
Gary Horen is the Program Manager for Ajax and Languages on the BEA Workshop team