Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Cross the Gap Between PHP and Java : Page 3

Using sophisticated application frameworks to build your network server applications is fine, but sometimes these frameworks are overkill. With a little communications programming between PHP and Java, you can establish an extensible layer that handles the annoying details of creating a custom network protocol.

Data Structures
To send the data back and forth, you put the two numbers to be added into a packet (in this case, just a PHP associative array) on the PHP side. Since PHP arrays are flexible and contain everything you need, you can easily put anything you need into the data packet. (The implementation for this article lets you put strings, integers, and floating-point values in the array. You can also put arrays inside arrays to any level of nesting.) The code in MapConnection converts the packet into a byte-stream, and then sends it across the wire to the server.

Meanwhile, on the Java side, this same data must be turned into a Java data structure. Java does not have dynamic arrays the way PHP does, but it does have the next best thing: the java.util.Map interfaces. Building and taking apart such structures is not as easy as it is in PHP, but it's semantically equivalent.

This data conversion is one of the fine points of communicating between PHP and Java. The previous code has defined a data structure—a dynamic associative array containing strings, integers, and floating point values—that can exist comfortably in both languages. It's then just a simple matter of writing code in both Java and PHP to convert these data structures to and from byte streams.

Abstracting Away the Details
The PHP and Java portions of this system aren't very complicated. Aside from the details of bundling and unbundling the data, and the addition itself, it contains very little code. This is as it should be: the application is simple, so the code is simple as well. The communication details, which are the same for all possible services, are kept out of sight. This is an excellent example of abstracting away the details.

You may think creating a custom server and a custom protocol to go with it is overkill for an application this simple. In fact, since PHP supports addition, this example really is overkill. But it makes perfect sense in other cases. For example, you might have a custom database implemented in Java, or you may want to interface with a Java-based chat system rather than trying to rewrite it in PHP. In either case, you'd just determine what you need to send back and forth, and use MapConnection and Server to take care of the communication for you.

Delving into the Details
The details are safely hidden from the user-level code, but how do they actually work?

On the Java side, you'll find five classes. The Server (see Listing 1) class deals with the networking. It listens on a socket and accepts connections. Each time a connection comes in, it creates an object called a Handler, which runs in its own thread. The Handler reads a request from the socket, calls transform() to process it, and sends the result back with the following code:

while (true) { Map map = min.readMap(); map = transform( map ); mout.write( map ); }

The default implementation of transform() just returns the packet unchanged. Of course, you can override this, as you did with AdditionServer (see Listing 2).

In the preceding code snippet, min and mout are instances of the classes MapInputStream (see Listing 3) and MapOutputStream (see Listing 4). These classes read and write Map objects and are subclasses of FilterInputStream and FilterOutputStream, respectively. Specifically, they handle Map objects, which contain strings, integers, doubles, and other Maps. In turn, these classes use DataInputStream and DataOutputStream, respectively, to encode integers, strings, and doubles. They both inherit an interface called MapStream (see Listing 5), which contains just a few constants that encode different kinds of values in the byte stream.

The process on the PHP side is rather similar. In fact, the code for readObject() and writeObject() are fairly similar among the PHP code in mapstream.PHP (see Listing 6) and the Java code in MapInputStream.java and MapOutputStream.java. PHP doesn't have DataInputStream or DataOutputStream, so you have to write those yourself and make sure they encode the data in the same way. This functionality is encoded in readRawInt(), writeRawInt(), readRawDouble(), writeRawDouble(), and so on. The similarities between the PHP and Java code are the results—and benefit—of using a data structure that is at home in both languages.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.