そのまんま!

LXXII. PHP / Java の連携

導入

PHP と Java の連携をとして考えられる手段は 2 種類あります。 PHP を Java サーブレット環境に統合する方法 と Java サポートを PHP に統合する方法です。前者のほうが より安定で効率的な手法です。前者は、サーブレットサーバへのインターフェイス として SAPI モジュールにより提供され、後者は Java 拡張モジュール として提供されます。

Java 拡張モジュールは、PHP から Java オブジェクトのメソッドを生成し、 コールする簡単で効率的な手段を提供します。この JVM は JNI を用いて 作成され、全てはこのプロセスで動作します。

警告

この拡張モジュールは、 実験的 なものです。この拡張モジュールの動作・ 関数名・その他ドキュメントに書かれている事項は、予告なく、将来的な PHP のリリースにおいて変更される可能性があります。 このモジュールは自己責任で使用してください。

要件

この拡張モジュールを使用するには、使用するマシンに Java VM が インストールされていることが必要です。

インストール手順

この PECL 拡張 モジュールは PHP にバンドルされていません。

PHP 4 の場合、この PECL 拡張モジュール のソースは、PHP のソースの ext/ ディレクトリ、または 上の PECL リンクで入手可能です。 これらの関数を使用するには --with-java[=DIR] を使用して Java サポートつきで PHP をコンパイルする必要があります。 DIR は JDK のインストールディレクトリを指します。この拡張モジュールは 共有モジュールとしてのみビルド可能です。詳細な情報は php-src/ext/java/README にあります。

Windows ユーザがこれらの関数を使用するには、php.ini 内で php_java.dll を有効にします。 PHP 4 の場合、この DLL は PHP の Windows ダウンロードバイナリの extensions/ ディレクトリ にあります。 この PECL 拡張モジュール用の DLL は、PHP のダウンロード ページあるいは http://pecl4win.php.net/ からダウンロードできます。

注意: Windows 環境において PHP <= 4.0.6 を使用してこのモジュールを有効に するには、jvm.dll をシステムの PATH が通った場所に おく必要があります。PHP > 4.0.6 では、追加の DLL は必要ありません。

実行時設定

php.ini の設定により動作が変化します。

表 1. Java 設定オプション

名前デフォルト変更の可否変更履歴
java.class.pathNULLPHP_INI_ALL 
java.homeNULLPHP_INI_ALL 
java.library.pathNULLPHP_INI_ALL 
java.libraryJAVALIBPHP_INI_ALL 
PHP_INI_* 定数の詳細および定義については 付録H を参照してください。

リソース型

リソース型は定義されていません。

定義済み定数

定数は定義されていません。

例 1. Java の例

<?php
// Java クラス java.lang.System のインスタンスをPHPに作成する
$system = new Java('java.lang.System');

// プロパティへのアクセスのデモ
echo 'Java version=' . $system->getProperty('java.version') . '<br />';
echo
'Java vendor=' . $system->getProperty('java.vendor') . '<br />';
echo
'OS=' . $system->getProperty('os.name') . ' ' .
             
$system->getProperty('os.version') . ' on ' .
             
$system->getProperty('os.arch') . ' <br />';

// java.util.Dateの例
$formatter = new Java('java.text.SimpleDateFormat',
                      
"EEEE, MMMM dd, yyyy 'at' h:mm:ss a zzzz");

echo
$formatter->format(new Java('java.util.Date'));
?>

例 2. AWT の例

<?php
// この例は、CGI として実行されることのみを考慮しています。

$frame  = new Java('java.awt.Frame', 'PHP');
$button = new Java('java.awt.Button', 'Hello Java World!');

$frame->add('North', $button);
$frame->validate();
$frame->pack();
$frame->visible = True;

$thread = new Java('java.lang.Thread');
$thread->sleep(10000);

$frame->dispose();
?>
注意:

  • new Java() は、有効なコンストラクタがある場合、 クラスのインスタンスを生成します。引数が指定されない場合には、 デフォルトのコンストラクタにより java.lang.Systemのようなクラスにアクセスすると 良いでしょう。このクラスは、ほとんどの機能を静的なメソッドとして 公開しています。

  • あるインスタンスのメンバーにアクセスする際には、まず bean プロパティ が探されてから、次に public フィールドが探されます。言い換えると、 print $date.time はまず $date.getTime() と解釈され、続いて $date.time と解釈されます。

  • 静的メンバおよびインスタンスメンバは共に同じ構文でアクセス可能です。 さらに、java オブジェクトが java.lang.Class 型の 場合、このクラスの静的メンバ(フィールドとメソッド)にアクセス可能です。

  • 例外が発生すると PHP の警告が出力され、結果は NULL となります。警告は "@" 記号を付けてメソッドをコールすることに抑圧できます。 直近のエラーを取得し、リセットするために以下の API を使用することができます。

  • オーバーロードの解決は、二つの言語の間で型の違いがあるため一般には 困難な問題です。PHP の Java 拡張機能は、どのオーバーロードが 最も一致するかを定義するための方法として、簡単ですがかなり 効率的なものを使用しています。

    加えて、PHP のメソッド名は大文字小文字を区別しないため、選択される オーバーロードの数は増加する傾向があります。

    メソッドが一度選択されると、パラメータの値は必要に応じて調整されます。 このため、(倍精度実数が論理値に変換されるといった)データの劣化が 発生する可能性があります。

  • PHP では伝統的に配列とハッシュテーブルは相互に完全に可換でした。PHP の ハッシュテーブルは整数または文字列の添字のみを使用できることに注意して ください。また、Java の primitive 型の配列は疎とすることができないことに も注意してください。これらの構造は値で渡されるため、メモリと時間の 消費量が大きくする可能性があります。

Java Servlet SAPI

Java Servlet SAPI は、PHP プロセッサ全体をサーブレットとして実行する ために、Java 拡張モジュールにより定義された機構の上に構築されています。 PHP の側からみてこの実装が基本的に優れている点は、サーブレットを サポートする Web サーバが通常 JVM をプールし、再利用することに注力している ことです。このサーブレット SAPI モジュールの構築手順は、 php4/sapi/README にあります。 注意:

  • このコードは、全てのサーブレットエンジンで実行可能であるように作成 されていますが、現在 Apache の Jakarta/tomcat でしかテストされていません。 他のエンジンでこのコードを実行する際に必要なパッチ、バグレポート、 成功事例等をお知らせください。

  • PHP は動作ディレクトリを変更する特徴があります。sapi/サーブレット はもとに戻そうとしますが、PHP が実行されている間、サーブレットエンジンは CLASSPATH に相対ディレクトリにより指定されている全てのクラスを ロードできないか、管理用および JSP コンパイル用に使用されている 作業ディレクトリを見つけることができなくなる可能性があります。

目次
java_last_exception_clear -- 直近の例外をクリアする
java_last_exception_get -- 直近の Java 例外を取得する