| | |
|
|
|
PHP to Java bridge
This article describes how to access Java classes from PHP using the PHP to Java bridge. The following sections provide a description of the bridge and examples of using it.
When to use the PHP to Java bridge
The Java bridge for PHP in Project Zero can help provide access to Java classes and functionality in PHP. This feature can help an application developer, for example, who wants to share a Project Zero library built in Java with the rest of the community. The expectation is that all data exchange occurs through the global context and any custom Java object placed by the library in the global context can be accessed in a PHP application through the bridge.
Note: Using the bridge requires PHP developers to read and understand the Javadoc for the classes that they are accessing. This requires PHP developers to understand the Java class.
If you do not want PHP developers to have to understand the Java class you can write an extension to the PHP language using the extension interfaces described in the Extending PHP article. This enables you to provide a PHP view of the function provided by the Java class.
Example
The following code snippet shows how to access Java classes from a PHP script.
<?php
$date = new Java("java.util.Date", 70, 9, 4);
var_dump($date->toString());
$map = new Java("java.util.HashMap");
$map->put("title", "Java Bridge!");
$map->put("when", $date);
echo $map->get("when")->toString()."\n";
echo $map->get("title")."\n";
$array = array(1,2,3,4,5);
$map->put("stuff", $array);
var_dump($map->get("stuff"))."\n";
$system = new Java("java.lang.System");
echo "OS: ".$system->getProperty("os.name")."\n";
$math = new Java("java.lang.Math");
echo "PI: ".$math->PI."\n";
?>
The new Java("java.util.Date", 70, 9, 4) call creates a new instance of the java.util.Date class using the java.util.Date(int year, int month, int day) constructor. Methods can then be called on the object and $date->toString() string returns the following information 'Sun Oct 04 00:00:00 GMT 1970'.
The new Java("java.util.HashMap") call creates a Java hash map. The script puts the date, a string, and an array into this collection and then retrieves them. Although the script creates a PHP array, what gets put into the hash map is a standard Java Map. The same applies to strings. The Java bridge converts a PHP string (essentially a byte array) into a java.lang.String string so that the Java class receives argument types that it would normally expect if the caller were another Java class.
The new Java("java.lang.System") call provides access to the java.lang.System class. Static methods can then be called on the class. The example invokes $system->getProperty(). The same applies to the java.lang.Math class although in this case the example code is accessing a public static field (PI) rather than a static method.
Using new Java()
new Java() creates an instance of a class if a suitable constructor is available. If no constructor is accessible, it provides access to the class instead. (Classes like java.lang.System expose most of their functionality through static methods.)
Accessing a member
Accessing a member of an instance will first look for bean properties then public fields. For example,= print $date->time= will first attempt to be resolved as $date->getTime(), then as $date.time. Both static and instance members can be accessed on an object with this syntax.
Overload resolution is in general a hard problem given the differences in types between the two languages. The Java to PHP bridge employs a simple, but fairly effective, metric for determining which overload is the best match. It chooses the method that has the best matching number of arguments (types are ignored). If there is not an exact match, then if a method exists that has less arguments than provided by the script it will be used. The opposite does not hold true, the Java to PHP bridge will not invoke a Java method that has more arguments than the script provides because Java does not have default arguments. Note that method names in PHP are not case sensitive, potentially increasing the number of overloads from which to select.
Once a method is selected, the parameters are coerced if necessary, possibly with a loss of data (example: double precision floating point numbers could be converted to boolean if that is what the Java method is expecting).
Exception handling
The Java to PHP bridge enables a PHP script to catch exceptions thrown from the Java code.
Since Java exceptions are not the same as PHP exceptions, there is some conversion required. All Java exceptions get converted into a generic PHP exception class called JavaException. The JavaException class allows a catch handler to find out the cause (to find out the Java exception that was thrown). All PHP exceptions inherit from the base PHP Exception class a message and code; for JavaException exceptions the code will always be zero and the message is the message extracted from the native Java exception.
The following sample code passes an invalid argument to getProperty() and then catches the java.lang.IllegalArgumentException.
<?php
try {
$system = new Java("java.lang.System");
$system->getProperty(FALSE);
} catch (JavaException $exception) {
echo "Cause: ".$exception->getCause()."\n";
echo "Message: ".$exception->getMessage()."\n";
}
?>
The cause is a simple text string containing the class name of the causing exception. The message in the exception is copied directly from the Java exception message (in this example the IllegalArgumentException contains no message and so displays nothing).
|
-- cjthorne - 14 Sep 2007
|
r5 - 15 Jan 2008 - 20:15:32 - paynel
|
|
|
| | |