php in java -quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

96
PHP in Java -Quercus- による レガシーマイグレーション 山下 竜司 株式会社アットウェア /Facebook4J #jjug_ccc #ccc_r12

Upload: ryuji-yamashita

Post on 13-Jun-2015

3.462 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP in Java -Quercus- による レガシーマイグレーション

山下 竜司 株式会社アットウェア/Facebook4J

#jjug_ccc #ccc_r12

Page 2: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

自己紹介•山下 竜司

•株式会社アットウェア

•@roundrop

•Facebook4J - http://facebook4j.org

Page 3: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12
Page 4: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12
Page 5: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12
Page 6: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP: Hypertext Preprocessor

Page 7: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

http://venturebeat.com/2013/05/17/google-app-engine-finally-supports-php-the-language-that-runs-75-of-the-web/

世界一 広まっている言語

Page 8: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

世界一 dis られている言語

Page 9: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus

https://www.flickr.com/photos/justinwkern/6140775849/

Page 10: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus•けっこう昔からあった

> svn log svn://svn.caucho.com/home/svn/svnroot/resin/trunk/modules/quercus

Page 11: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus•PHP (PHP5 相当) を Java 上で動かすことを可能にする Java で実装されたエンジン

Page 12: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus•PHP (PHP5 相当) を Java 上で動かすことを可能にする Java で実装されたエンジン

•オープンソース (ライセンスは GPL)

Page 13: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus•PHP (PHP5 相当) を Java 上で動かすことを可能にする Java で実装されたエンジン

•オープンソース (ライセンスは GPL)

•Caucho Technology 社の商用アプリケーションサーバー Resin の一部

Page 14: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP アプリといえば WordPress

Page 15: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

WordPress on Quercus デモ

Page 16: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

WordPress on Quercus デモ

!

https://gist.github.com/roundrop/4977262

Page 17: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Links•Home

‣ http://quercus.caucho.com/

•Change Log

‣ http://caucho.com/resin-4.0/changes/changes.xtp

•ソースコード

‣ svn://svn.caucho.com/home/svn/svnroot/resin/trunk/modules/quercus

•バグトラッカー

‣ http://bugs.caucho.com/view_all_bug_page.php

見た目に反して 開発はわりとアクティブ

Page 18: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus の構造•実体は Servlet ※Servlet 以外の起動方法もあるが割愛

[web.xml] <servlet> <servlet-name>Quercus Servlet</servlet-name> <servlet-class> com.caucho.quercus.servlet.QuercusServlet </servlet-class> <init-param> : </servlet> <servlet-mapping> <servlet-name>Quercus Servlet</servlet-name> <url-pattern>*.php</url-pattern> </servlet-mapping>

Page 19: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus の構造

QuercusServlet

Tomcat など

xxxx.php

1. phpファイル読込 2. 解析 3. 実行

Page 20: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP コードの再現力•Quercus の PHP 再現力はかなりのもの

• (モノによるが) だいたい 90% 以上のコードは動く

•逆に言うとある程度は改修・実装が必要

‣ Quercus で未実装の PHP 関数の自前実装

‣対応していないシンタックスを調整 など

Page 21: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP コードの実行速度•速い

•素の PHP より速くなる事例もある

•キャッシュ、コネクションプールなど Java 資産が使える

•プロダクションに投入できるレベル

Page 22: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP から Java のコードを呼び出せる

•Java 上での PHP コードの実行だけでなく、PHP コードから Java のコードを呼び出せる

Page 23: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP から Java のコードを呼び出せる

•Java 上での PHP コードの実行だけでなく、PHP コードから Java のコードを呼び出せる

<?php import java.lang.System; import java.util.Date; $date = new Date(); System::out->println($date);

Page 24: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP から Java のコードを呼び出せる

QuercusServlet

Tomcat など

xxxx.php

Java コード 呼び出し

Java Class

Page 25: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

つまり、•PHP アプリを Tomcat 等の上で動かしつつ

Page 26: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

つまり、•PHP アプリを Tomcat 等の上で動かしつつ

•これからつくる新機能は Java で開発したり

Page 27: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

つまり、•PHP アプリを Tomcat 等の上で動かしつつ

•これからつくる新機能は Java で開発したり

•PHP の処理の一部だけ Java に置き換えたり

Page 28: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

つまり、•PHP アプリを Tomcat 等の上で動かしつつ

•これからつくる新機能は Java で開発したり

•PHP の処理の一部だけ Java に置き換えたり

レガシーマイグレーションに使える

Page 29: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Java Application Server (Tomcat など)

PHP

Page 30: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Java Application Server (Tomcat など)

PHPJava

(Spring等)既存機能はPHPのまま 新機能はJava

Page 31: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Java Application Server (Tomcat など)

PHPJava

(Spring等)既存機能はPHPのまま 新機能はJava

性能上のボトルネックだけ Java 化

Page 32: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Java Application Server (Tomcat など)

PHPJava

(Spring等)既存機能はPHPのまま 新機能はJava

あまりにひどい部分だけ Java 化性能上のボトルネックだけ Java 化

Page 33: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Java Application Server (Tomcat など)

PHPJava

(Spring等)既存機能はPHPのまま 新機能はJava

あまりにひどい部分だけ Java 化性能上のボトルネックだけ Java 化

スモールスタートしてから徐々に Java の範囲を 広げていき、最終的には PHP をなくす

Page 34: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

実践

https://www.flickr.com/photos/pshab/1366448271/

Page 35: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

まずは PHP をまともに動かす

Page 36: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP をまともに動かすまでの障壁•文字化け

•Quercus が解釈できないシンタックス

•Quercus で未対応な PHP 関数

Page 37: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP をまともに動かすまでの障壁•文字化け

•Quercus が解釈できないシンタックス

•Quercus で未対応な PHP 関数

Page 38: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•既存 PHP アプリを Quercus 上で動かしてみたところ絶望的に文字化け

Page 39: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•既存 PHP アプリを Quercus 上で動かしてみたところ絶望的に文字化け

•Java でつくる部分は UTF-8 にしたいので、全体的に UTF-8 で統一したい

Page 40: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•文字コードを UTF-8 に揃える

‣ソースコード

‣画面の charset

‣データベース

‣リソースファイル

‣:

Page 41: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•Quercus は ISO-8859-1 前提で動作する

•unicode.semantics=on

‣ on にすることで UTF-8 前提で動作するようになる

‣ php.ini に書いて Quercus に読み込ませる

Page 42: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•QuercusServlet に ini-file パラメータを指定

[WEB-INF/php.ini] unicode.semantics=on ![web.xml] <servlet> <servlet-name>Quercus Servlet</servlet-name> <servlet-class> com.caucho.quercus.servlet.QuercusServlet </servlet-class> <init-param> <param-name>ini-file</param-name> <param-value>WEB-INF/php.ini</param-value> </init-param> :

Page 43: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策

QuercusServlet

Tomcat など

xxxx.php

php.iniunicode.semantics=on で動作モードを ISO-8859-1 → UTF-8 に変更

Page 44: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•文字化けの発生する可能性のある箇所

‣画面に記述した日本語の表示

‣GET/POST した日本語パラメータの表示

‣DB に入っている日本語の表示・登録

‣セッションに入れた日本語の表示

‣ファイル入力・出力

‣ログ  などなど

Page 45: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•アップロードファイル名

‣最新版でも文字化け

‣ファイル名が重要な場合は commons-fileupload の実装に差し替えるなどの対応が必要

‣ com.caucho.quercus.env.Post#fillPost()

Page 46: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

文字化け対策•UTF-8 以外でのレスポンス出力

‣ Excel 前提だから CSV ファイルのダウンロードは SJIS で、といった要件のとき

‣ “SJIS-win” → “Windows-31J”

‣ print じゃなくて echo を使うprintf("%s\r\n", mb_convert_encoding($data, "SJIS-win", "UTF-8")); ↓ echo mb_convert_encoding($data, "Windows-31J", "UTF-8")."\r\n";

Page 47: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP をまともに動かすまでの障壁•文字化け

•Quercus が解釈できないシンタックス

•Quercus で未対応な PHP 関数

Page 48: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

解釈できないシンタックス•動的に変数名やクラス名を決定するシンタックスは Quercus が解釈できない

!

!

!

!

‣そうしないように修正するしかない

$code = "red"; $color_{$code} = "..."; //$color_red = ..

$name = "Login"; $action = new {$name}Action(); //LoginAction

Page 49: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP をまともに動かすまでの障壁•文字化け

•Quercus が解釈できないシンタックス

•Quercus で未対応な PHP 関数

Page 50: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

未対応な PHP 関数•Quercus は未実装関数を検知した場合、

UnimplementedException を投げる

•特にマルチバイト系の関数(mb_****) の未実装 or 不備が多い

‣ mb_convert_kana : 未実装

‣ mb_send_mail : 不備

‣ mb_encode_numericentity : 未実装  などなど

Page 51: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

未対応な PHP 関数•PHP 関数については同じ名前のメソッドがあるのでわりとわかりやすい

Page 52: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

未対応な PHP 関数

•以下のいずれかで対応

‣自力で Quercus を改変してビルド

‣ AOP でひっかけて実装

‣ PHP の呼び出し箇所を Java 化する

Page 53: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP と Java を

結合してみる

Page 54: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP - Java 結合のポイント•セッション情報

‣ Quercus - JavaEE 間セッション情報共有

‣セッションタイムアウト設定

•PHP ファイルの配置方法

•ビューレイアウト共有

Page 55: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP - Java 結合のポイント•セッション情報

‣ Quercus - JavaEE 間セッション情報共有

‣セッションタイムアウト設定

•PHP ファイルの配置方法

•ビューレイアウト共有

Page 56: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Tomcat など

PHP Java

PHP 5.2 Spring など

$_SESSION

• Quercus を使っても、  PHP のセッションと Java のセッションは別空間  になる !

HttpSession

Page 57: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Tomcat など

PHP Java

PHP 5.2 Spring など

$_SESSION

• Quercus を使っても、  PHP のセッションと Java のセッションは別空間  になる • なんらかの方法で、2つの空間を同期する仕組みが必要

HttpSession

Page 58: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Quercus-JavaEE セッション情報共有

•Quercus から HttpSession は参照できる

•PHP の auto_prepend 及び auto_append のしくみが Quercus でも使えるのでこれで同期

‣ auto_prepend‣ Java(HttpSession) → PHP($_SESSION)

‣ auto_append‣ PHP($_SESSION) → Java(HttpSession)

Page 59: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

auto_prepend/auto_append で同期

QuercusServlet

Tomcat など

xxxx.php

php.ini

Page 60: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

auto_prepend.php

auto_prepend/auto_append で同期

QuercusServlet

Tomcat など

xxxx.php

php.iniauto_append.php

PHP($_SESSION) → Java(HttpSession)

Java(HttpSession) → PHP($_SESSION)

Page 61: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

auto_prepend/auto_append で同期

•php.ini に以下のように記述auto_prepend_file=/path/to/before.php auto_append_file=/path/to/after.php

[before.php: Java -> PHP] <?php session_start(); $request = quercus_servlet_request(); $session = $request->getSession(); $keys = $session->getAttributeNames(); while ($keys->hasMoreElements()) { $key = $keys->nextElement(); $value = $session->getAttribute($key); $_SESSION[$key] = $value; }

[after.php: PHP -> Java] <?php session_start(); $request = quercus_servlet_request(); $session = $request->getSession(); foreach ($_SESSION as $key => $value) { $session->setAttribute($key, $value); }

Page 62: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Tomcat など

PHP Java

Quercus Spring など

$_SESSION

• session-config ‣ HttpSession にのみ適用される

!!!!

HttpSession

Page 63: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Tomcat など

PHP Java

Quercus Spring など

$_SESSION

• session-config ‣ HttpSession にのみ適用される

• Quercus 管理の PHP セッション ‣ デフォルト 30 分で変更する手段なし? ‣ リフレクションで変更して Quercus がもっているタイマーを起動すればなんとかできる

HttpSession

Page 64: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

セッションタイムアウト•アプリケーション起動時に 1 回 Quercus がもっているセッション管理のタイマーを起動すれば OK

•コードは長いので Gist に書きました

‣ https://gist.github.com/roundrop/96edc5f4d7135e60a2d0

Page 65: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP - Java 結合のポイント•セッション情報

‣ Quercus - JavaEE 間セッション情報共有

‣セッションタイムアウト設定

•PHP ファイルの配置方法

•ビューレイアウト共有

Page 66: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

機能B

Page 67: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

Java アプリ

web ルート

WEB-INF

機能B

Page 68: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

Java アプリ

web ルート

WEB-INF

機能B

Page 69: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

Java アプリ

web ルート

WEB-INF

機能A

index.phpいろいろ汚いの

機能B 機能B

include

ドキュメントルートをwebルートとして配置

Page 70: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

Java アプリ

web ルート

WEB-INF

機能A

index.phpいろいろ汚いの

機能B 機能B

include

ドキュメントルートをwebルートとして配置

Page 71: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

Java アプリ

web ルート

WEB-INF

機能A

index.phpいろいろ汚いの

機能B 機能B

include

ドキュメントルートをwebルートとして配置web ルートがきたなくなる 一部階層関係がかわってしまう (この例だと htdocs と include)

Page 72: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置•階層関係重要

•こういうのありがち

!

!

!

!

•階層関係は変えないのが望ましい

htdocs/sub/hoge.php !<?php define('_ROOT', "../.."); define('_INCLUDE', _ROOT."/include"); :

Page 73: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

Java アプリ

web ルート

WEB-INF

機能B

Page 74: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置既存 PHP

Apache

htdocs (docルート)

include

機能A

index.phpいろいろ汚いの

Java アプリ

web ルート

WEB-INF

機能B

phphtdocs

機能A

index.phpいろいろ汚いの

機能B

include

1つのディレクトリにそのままの構成で配置

Web サーバーで *.php を /php/htdocs へプロキシーする

Page 75: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP ファイルの配置•auto_prepend でサーバー変数を調整$_SERVER['SCRIPT_NAME'] = str_replace("/php/htdocs", "", $_SERVER['SCRIPT_NAME']); $_SERVER['SCRIPT_URL'] = str_replace("/php/htdocs", "", $_SERVER['SCRIPT_URL']); $_SERVER['REQUEST_URI'] = str_replace("/php/htdocs", "", $_SERVER['REQUEST_URI']); $_SERVER['PHP_SELF'] = str_replace("/php/htdocs", "", $_SERVER['PHP_SELF']); $_SERVER['DOCUMENT_ROOT'] = $_SERVER['DOCUMENT_ROOT']."php/htdocs/";

Page 76: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP - Java 結合のポイント•セッション情報

‣ Quercus - JavaEE 間セッション情報共有

‣セッションタイムアウト設定

•PHP ファイルの配置方法

•ビューテンプレート共有

Page 77: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

ビューテンプレート共有•PHP と Java の両方が動いているとはいえ、サイトとしては 1 つで、デザインも同じ

‣サイトのヘッダーやフッターなどの部品は PHP と Java で共有したい

‣ Java のテンプレートエンジンでデザインして、PHP でもそれを使うのが理想

Page 78: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

ビューテンプレート共有<?php : include_once 'header.php'; : [コンテンツ] :

<header> デザインした内容 :

: : <header th:include="header... : [コンテンツ] :

<header> デザインした内容 :

PHP Java (Thymeleaf)

header.php header.html

Page 79: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

ビューテンプレート共有<?php : include_once 'header.php'; : [コンテンツ] :

<header> デザインした内容 :

: : <header th:include="header... : [コンテンツ] :

<header> デザインした内容 :

PHP Java (Thymeleaf)

header.php header.html

デザインテンプレートが二重管理 DRY じゃない

Page 80: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

ビューテンプレート共有<?php : include_once 'header.php'; : [コンテンツ] :

: : <header th:include="header... : [コンテンツ] :

PHP Java (Thymeleaf)

<header> デザインした内容 :

<?php import aa.bb.XxxReader; print XxxReader::readHeader();

header.php header.html

Page 81: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

: : <header th:include="header... : [コンテンツ] :

ビューテンプレート共有<?php : include_once 'header.php'; : [コンテンツ] :

PHP Java (Thymeleaf)

<header> デザインした内容 :

<?php import aa.bb.XxxReader; print XxxReader::readHeader();

header.php header.html

PHP では ・Java テンプレートエンジンの html ファイルを読み込み ・テンプレートエンジン特有のアトリビュート(th: 等)を削除 ・static 変数にキャッシュするなど

Page 82: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

その他

Page 83: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

その他•PHP の一部を Java に置き換える

•ロギング

•コネクションプーリング

Page 84: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

その他•PHP の一部を Java に置き換える

•ロギング

•コネクションプーリング

Page 85: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP の一部を Java に置き換える•PHP から Java を扱う

‣ http://quercus.caucho.com/quercus-3.1/doc/quercus.xtp#JavaPHPintegration

• import して使う方法

!

!

•new Java(“…”) する方法

<?php import java.util.Date; $a = new Date(123);

<?php $a = new Java("java.util.Date", 123);

Page 86: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

: <?php if ($user->is_premium) { : ?> <div><?php echo $user->name; ?></div> <div>ここに表示項目を追加したい</div> :

PHP の一部を Java に置き換える

Page 87: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP の一部を Java に置き換える: <?php if ($user->is_premium) { : ?> <div><?php echo $user->name; ?></div> <?php import com.example.helper.StatusHelper; ?> <div><?php echo StatusHelper::getLabel($user->status); ?></div> :

Page 88: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

PHP の一部を Java に置き換える•Java の型 → PHP の型 の変換ルール‣ http://quercus.caucho.com/quercus-3.1/doc/

quercus.xtp#MarshallingPHPtoJavaconversions

‣ 例えば java.util.List は array になる

<?php import com.example.php.ContactLogic; $logic = new ContactLogic(); $recents = $logic->getRecents(); foreach ($recents as $contact) { $from = $contact["from"];

public final class ContactLogic { : public List<Contact> getRecents() { :

Page 89: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

その他•PHP の一部を Java に置き換える

•ロギング

•コネクションプーリング

Page 90: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

ロギング•Quercus 内部では java.util.logging が使われている

•error_log 関数については、ログタイプ=0 の場合、error_log ディレクティブに “syslog” を指定すると java.util.logging.Logger で出力される

!

!

• jul-to-slf4j を使って SLF4J に集約するとよい

<?php ini_set("error_log", "syslog"); error_log("メッセージ", 0);

Page 91: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

その他•PHP の一部を Java に置き換える

•ロギング

•コネクションプーリング

Page 92: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

コネクションプーリング•Quercus ならではの強力機能!

•mysql_connect(), pg_connect() や PDO で JNDI から接続をとってきて使用できる

‣ $con = pg_connect(“java:comp/env/jdbc/mydb”);

‣ $pdo = new PDO(“pgsql:java:comp/env/jdbc/mydb”);※PDO の場合は先頭に「データベース名:」が必要なので注意

Page 93: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

コネクションプーリング•Web サーバーのContext に jdbc リソースを追加

•web.xml に以下を記述<servlet> <servlet-name>quercusServlet</servlet-name> <servlet-class> com.caucho.quercus.servlet.QuercusServlet </servlet-class> : <init-param> <param-name>database</param-name> <param-value>jdbc/mydb</param-value> </init-param> :

Page 94: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

Maven 形式 / JDK 7 でビルド可能な Quercus を GitHub に置いています

https://github.com/roundrop/quercus!

(サンプルコードもそのうち GitHub に置きます)

Page 95: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

まとめ•Quercus けっこううまく動く

•でも完璧ではないので、プロダクションレベルで適用するには多少の労力をかける必要はある

•うまくハマれば「段階的に」PHP→Java へ進化させられる

Page 96: PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12

ありがとうございました