Using PHP-Java Bridges with WebLogic Server
by Gary Horen
02/13/2007
Abstract
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.
Introduction: What is a PHP-Java Bridge?
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.
Why Use a 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:
- PHP code can instantiate and call methods on a Java object, either a POJO or a Java EE resource like an EJB.
- You can use WebLogic Server as the Web server for pages coded in PHP.
- Java code can invoke PHP scripts.
The first two cases are illustrated below. The third is left for a future discussion.
Available Implementations
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);
}
Hints and Help
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.
The Zend Platform Bridge
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.
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:
- The PHP request arrives and is passed by Apache to the PHP engine.
- When the PHP script issues a "new Java()" call, the bridge passes the request to a JVM it has instantiated. POJO requests can be serviced inside that JVM.
- From there, access to JNDI resources happens in the usual way.
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);
The SourceForge Bridge
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:
- Download a version from the SourceForge site. We used php-java-bridge_3.2.1_j2ee.zip for this tutorial.
- Open the zip file and extract JavaBridge.war.
- Explode JavaBridge.war into a new folder in an Eclipse workspace. (We called it "JavaBridge".)
- If you want to use Workshop Studio:
-
- You must use version 3.2 or higher. You can download it
- Using the new Workshop Studio New Project Wizard, create a Dynamic Web Project From Existing Source in that workspace. Set the Web context root to /JavaBridge.
- Point to the folder into which you exploded the .war file. (Unfortunately, a problem in WTP currently prevents simply importing the .war file as a project.)
- Deploy the application to WebLogic Server, either with Studio or with another tool of your choice.
- Point a Web browser at http://localhost:7001/JavaBridge. The index.php will present several example programs that demonstrate the bridge.
Figure 2. Running SourceForge Java Bridge as a PHP servlet
In this configuration:
- The PHP request arrives and is mapped by WebLogic Server to the bridge's PHP servlet.
- The PHP script is passed to a php-cgi instance for processing.
- The bridge passes calls to Java objects into the WebLogic Server JVM through requests to its Java Gateway servlet.
- From there, access to JNDI resources happens in the usual way.
Helpful hints:
- In the servlet configuration, by default, this bridge shells out a CGI process for each invocation of PHP, which terminates at the end of the request. In an environment where more than an occasional PHP request is run, this can lead to performance problems. The bridge distribution contains instructions for configuring FastCGI, which will maintain a pool of PHP address spaces and dispatch incoming requests to idle ones; this approach avoids the overhead of operating-system process initiation and termination for each request. The challenge involved in setting up this feature varies among operating-system platforms.
Sample Code: Accessing a Resource that Lives in WebLogic Server
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:
- Add ejbref.php to the JavaBridge Web root (either to the Eclipse project described above for the SourceForge bridge, or to the directory in the Zend platform which contains the test.php script.
- Make TraderClient.jar available to the bridge: Add to the environment classpath for the Zend bridge or to WEB-INF/lib in the deployed servlet app for the SourceForge one.
- Deploy the Trader.ear file to the target WebLogic server.
- Point your browser at the deployed ejbref.php script and run.
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>
Tools
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.
Summary
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.
References
Gary Horen is the Program Manager for Ajax and Languages on the BEA Workshop team