PHPをJava VMで動かしたいと思ったので、いろいろ調べてみた。
Java VM用のPHPとしては、現状でCaucho QuercusとPROJECT ZEROのP8があるようだ。
どちらもPHP5.2をターゲットにしているみたい。
P8
ここで、PROJECT ZEROのP8の方は、WebSpere sMeshの一部みたいで、単独では配布してなさそう。試してない。Tomcatで使えるんだろうか?
けど、IBMがやってるということで、今後が期待できそう。
http://www.projectzero.org/
Quercus
Quercusのほうは、Resin作ってるCauchoがやってる。前はResinじゃないと動かなかったようだけど、今はTomcatでも動く。ただしどこまで動くかは調べてない。
PHPの関数は全部Javaで書き直されてて、mbstringとかgdとかも実装されてる。もちろん、PostgreSQLやMySQLも使える。JDBC接続はPDOでできる。
サイトの記述によると、mod_phpの4倍の速さで動くらしい
ただ、ソースみたけど、コマンドライン版の入り口になるmainメソッドがみあたらないので、コマンドラインからは呼び出せない。最新版のソースがnot foundだったので、もしかしたら今はできるのかも。
http://quercus.caucho.com
JavaとPHP
PHPは動的型付けの言語だけど、言語として動的な仕組みはほとんど持ってない。変数の型解決とevalくらいじゃないだろうか。
オブジェクト指向に対応したけど、オブジェクト指向プログラムができるという話で、言語自体がオブジェクト指向言語というわけではない。
オブジェクト指向機能もJavaのマネをして作られている。参考にしたというより、見よう見まねで実装した感じ。
ということで、PHPのクラスをJavaのクラスに変換するとかは、非常に相性がよさそう。関数は動的に解決されるといっても、標準関数は一意に決まるので、静的にコンパイルできる。そいういうわけで、P8もquercusもJavaのクラスに変換して実行されるみたい。
invokeDynamicの恩恵を一番うける言語は、PHPなんじゃなかろうか
NetBeansとPHP
NetBeansからTomcat/GlassfishにPHPアプリケーションを配備して動かすとかやるときには、P8がIBMのものということで、Cauchoと仲良くしないといけないんじゃないだろうか。
ただ、その場合はライセンスが問題になりそう。
Quercusを動かしてみる
Quercusのバイナリはここでwarファイルをダウンロード。
http://quercus.caucho.com/#Downloads
ダウンロードしたwarファイルを展開すると、とりあえず使えるWebアプリケーションのフォルダ構成になってる。展開は、拡張子をzipに変えてダブルクリックとかが楽。
既存のWebアプリなどでPHPを使えるようにしたい場合は、展開したフォルダのWEB-INF/libにある
javamail-141.jar
quercus.jar
resin-util.jar
をWebアプリのWEB-INF/libにコピーする。すでにactivation.jarやmail.jarを使ってるなら、おそらくjavamail-141.jarは不要。
web.xmlには次のようなサーブレット定義を記述する。
<servlet> <servlet-name>Quercus Servlet</servlet-name> <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class> <init-param> <param-name>script-encoding</param-name> <param-value>UTF-8</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Quercus Servlet</servlet-name> <url-pattern>*.php</url-pattern> </servlet-mapping>
<html><body> <?php for($i = 0; $i < 3; ++$i){ echo $i . "です<br>"; } phpinfo(); ?> </body></html>
import javax.swing.JFrame; $f = new JFrame("こんにちは"); $f->visible = true;
などと書くと、このページにアクセスしたときに、ちゃんとSwingのウィンドウが表示される。あたり前なんだけど、PHPでできるというのがバカらしくていい。
データベースもPDOでJDBCが使える。このときはデータソースの設定が必要。
Tomcat6やGlassfishだと、META-INF/context.xmlにこんな記述をしておく。
<?xml version="1.0" encoding="UTF-8"?> <Context path="/WebApplication1"> <Resource auth="Container" name="jdbc/shohin" type="javax.sql.DataSource" driverClassName="org.apache.derby.jdbc.ClientDriver" url="jdbc:derby://localhost/sample" username="db" password="db" /> </Context>
で、web.xmlにresource-refを追加。これは実際は不要かもしれない。
<resource-ref> <res-ref-name>jdbc/sample</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
そうすると、こういう記述でデータベースのデータが表示できる。
<html><body> <?php $pdo = new PDO("java:comp/env/jdbc/shohin"); $sql = "SELECT * FROM SHOHIN"; foreach($pdo->query($sql) as $row){ echo $row['SHOHIN_NAME']."<br>"; } ?> </body></html>
けども、日本語は化けてしまった。
まだ解決策は試してない。
ところで、mb_convert_encodingで引数3つ使うと、マシンが飛んでしまうのだけど、これはぼくの環境だけだろうか?Java SE 6 update 11/Windows XPなんだけど。