現在,PHPは世界中の全ドメインの32%に相当する約1400万ドメイン(英Netcraftの2003年10月の統計データによる)のWebサイトにインストールされており,Webアプリケーションの代表的な実行環境のひとつとなっている。現在の最新バージョンはPHP 4.3.3であるが,次期バージョンにあたるPHP5も開発中である。10月30日β2がリリースされ,このまま順調に開発が進めば,2004年の早い時期に正式版がリリースされる見込みだ。

10月のPHPConで,コア・メンバーがPerl6用エンジン「Parrot」採用を提案

 PHP開発のコア・メンバーであるThies Arntzen氏とSterling Hughes氏により,10月22日から10月24日にかけて米国で開催されたPHPCon West 2003のクロージング・キーノートにおいて「PHP and Parrot」と題する発表が行われた。この中で,Perl6用に開発中のスクリプト・エンジンParrotをPHPのスクリプト・エンジンとして使用する提案がなされている。実験的な実装でのマンデルブロ・フラクタル生成に関するベンチマーク・テスト結果により,JIT(Just In Timeコンパイラ)なしのParrotで約5倍,JITありのParrotで約30倍の高速化がなされたことが示された。

 Parrotの完成までにはまだ多くの作業が必要であるが,完成時にはPerlのみならずPHPなどの複数のスクリプト言語のスクリプト・エンジンとして採用され,例えば,Perlで書かれたライブラリのモジュールをPHPから呼び出すといったことが可能になると期待される。CPANなどのサイトに蓄積された膨大な数のperlライブラリを使用できるメリットは大きいものと思われる。

 先日,PHPの作者であるRasmus Lerdorf氏が来日し,日本PHPユーザー会のメンバーとディスカッションを行ったが,Lerdorf氏もPHP6でのParrotの採用について前向きな姿勢を示していた。Lerdorf氏は「複数のスクリプト言語をサポートするスクリプト・エンジンの存在は,性能面の利点以上に開発効率の大幅向上という利点をもたらすだろう」と述べている。

 PHP5が開発中だというのに気が早いと思われるかもしれないが,今後のPHPの進化の方向として注目される。以下,PHP5の詳細について解説しよう。最大の変更点であるオブジェクト機能の拡張の概要を紹介する。また,間もなくリリースされるPHP 4.3.4での変更点についてもとりあげる。

PHP5のポイントはオブジェクト,エンジン,拡張モジュール

 PHP5における機能強化のポイントを以下に示す。

(1) オブジェクト機能の大幅強化
 PHP4は高い評価を受けているものの,オブジェクトの扱いに弱点があると指摘されてきた。この弱点を克服するために,PHP5では,オブジェクト機能が大幅に強化される。

(2) スクリプト・エンジンの強化
 PHPスクリプトの実行処理を行うスクリプト・エンジンであるZendEngineがバージョン2(ZendEngine2)となり,上記オブジェクト機能の強化や例外処理の実装などの機能が強化される。

(3) 拡張モジュールの強化
 XML機能の強化や簡易データベースSQLiteの標準バンドルなど拡張モジュールの機能強化が行われる。

 上記のポイントのうち,最も注目されるのはオブジェクト機能に関するものである。その主な内容を以下に示す。

1. オブジェクトの代入がディープ・コピーからシャロー・コピーに変更
2. 統一されたコンストラクタ,デストラクタの導入
3. メンバ変数およびメソッドへのアクセス制限(private,protected)の導入
4. メンバー変数でスタティック(static)宣言が可能になる
5. final宣言により派生クラスでの上書きを禁止可能
6. クラス定数の導入
7. ネストしたクラスの間接参照(例:$foo->a->b)の導入
8. _autoload()関数によるクラス定義の自動的ロードが可能に
9. _get(),_set()メソッドにより未実装のクラス変数の値の取得,設定が可能に
10. _call()メソッドにより未実装のメソッドがコールされた場合に対応可能
11. abstract宣言により抽象クラスを宣言可能
12. interface宣言によりクラスのインタフェース定義およびimplementsによるインタフェース定義の強制が可能に
13. タイプ・バインディングの導入

 以下では,このオブジェクト機能の強化ポイントのうち主要なものについて紹介する。

オブジェクト・モデルが変更,移行時には注意を

図1●ディープ・コピー(上)
とシャロー・コピー(下)
 上記1は,オブジェクトのコピーに関するものである。コピーを行う際には,図1に示すようなディープ・コピー(Deep copy)とシャロー・コピー(Shallow copy)と呼ばれる2種類の方法のどちらかが用いられる。

 ディープ・コピーの場合は,変数をコピー(代入)する際に参照するオブジェクトの実体もコピーされ,別の実体(クローン)が作成される。(図1上)。一方,シャロー・コピーの場合は,変数をコピーした場合も,参照するオブジェクトの実体はコピーされず,コピー先はコピー元と同じ実体を参照することになる(図1下)。

 ディープ・コピーを行う実装では,大量のデータを含むオブジェクトをコピーするため,参照カウンタを増やすだけのシャロー・コピーに比べて実行効率が悪くなると言われている。

 PHP4における代入ではディープ・コピーがデフォルトであり,シャロー・コピーを行うためには,リファレンス指定子(&)を用いる必要があった。

 一方,PHP5では,シャロー・コピーがデフォルトとなり,リファレンス演算子を付加しなくてもオブジェクトの非効率なコピーは行われなくなる。なお,PHP5においてディープ・コピーを行う必要がある場合には,_clone()メソッドを用いる。

PHP4シャロー・コピーによる代入$b =& $a;
$b = $a;
PHP5ディープ・コピーによる代入$c = $a;
$c = $a->_clone();

 このオブジェクトモデルの変更により,PHP5ではオブジェクトを多用するスクリプトの実行効率が向上すると考えられる。ただし,PHP4においてディープ・コピーを前提とするコードを用いていた場合には,PHP5への移行時に変更が必要となる。移行時には十分な動作確認を行う必要がある。

統一されたコンストラクタ・デストラクタを導入

 クラスからオブジェクトが生成される際に自動的に実行されるメソッドをコンスラクタと呼ぶ。PHP4までは,クラスのコンストラクタはクラス名と同一のメソッドとして定義されていた。PHP5では,コンストラクタの名前は,_construct()に統一される。これにより,オブジェクト生成を一括して行うfactoryメソッド・パターンなどに則ったプログラムの作成が容易になると思われる。

 オブジェクトが破棄される際に自動的に実行されるメソッドをデストラクタと呼ぶ。PHP4ではデストラクタはサポートされていなかったが,PHP5ではクラスのデストラクタ_destruct()を定義できるようになる。これにより,クラスの実体が消滅する際,クラスが保持するリソースについて独自の終了処理を行うといった処理の実装が可能となる。

class Hello {
function __construct(){
 print "constructor called.\n";
}
function __destruct(){
 print "destructor called.\n";
}
}
$a = new Hello();
unset($a);  // 実体参照がなくなるため,自動的にデストラクタがコールされる
?>

プロパティやメソッドへのアクセス制限でカプセル化を容易に

 PHP4において,クラスのプロパティ(メンバ変数)はvarで定義され,すべてpublicとして扱われていた。このため,外部から自由に参照・変更することが可能で,コードの隠蔽(カプセル化)が困難であった。

 PHP5では,JavaやC++と同様にprivateおよびprotectedといった修飾子によるアクセス制限(下記)が可能となる。

Public外部参照が自由に可能
Private同一クラスのメソッド内からのみ参照可能
Protected同一クラスまたはその派生クラスからのみ参照可能

 例えば,以下のコードでは11行目で変数$aに直接アクセスしようとしているが,private宣言されているために致命的エラーを発生する。
1  2 class Hello {
3  private $a='PHP';
4  function get_a() {
5   return $this->a;
6  }
7 }
8
9 $obj = new Hello();
10 print $obj->get_a(); // こちらはアクセス可能
11 print $obj->a; // 直接参照はできないため,致命的エラーを発生
12 ?>

ライセンスやファイル・アップロード時の問題を解消したPHP4.3.4

 現行のPHP4の最新バージョンはPHP4.3.3であるが,バグ修正版にあたるPHP4.3.4の開発が進められており,9月末にリリース候補第2版(RC2)がリリースされるなど,リリース間近の段階にある。

 このバージョンにおける変更点の多くはバグ修正であるが,マルチバイト文字を処理する拡張モジュールmbstringに関して変更が行われている。使用するユーザーは,現在使用しているアプリケーションで問題が生じないことを確認した上で,このバージョンにアップデートすることが望ましい。このバージョンにおけるマルチバイト関連の変更・修正点を以下に示す。

1. 前回紹介したライセンス問題を解消するため,mbfilterから度独立した外部ライブラリlibmbflを使用する実装へ変更された。ただし,libmbflと従来のmbfilterから派生したコードをベースにしており,動作上の差異を発生する可能性は小さい。この変更内容の詳細については,前回のコラムを参照いただきたい。

2. PHP4.3.3で追加されたファイル・アップロード時(POSTメソッドによるフォームでenctype="multipart/form-data" を指定した場合)におけるエンコーディング検出・変換機能に関する修正が行なわれた。4.3.3ではmbstring.http_inputにpass(変換なし)を指定しても,mbstring.encoding_translation=Onが指定されているとエンコーディングの自動検出が行われ,内部エンコーディングへの変換が行われていた。PHP4.3.4では通常のフォームにおけるPOST/GET/Cookie変数の処理と同様に,passが指定された場合には変換が行われないように変更された。また,mbstring.http_inputに有効なエンコーディングが指定されている場合にも自動検出が行われていたが,PHP 4.3.4では指定したエンコーディングが使用されるようになった。

3. マルチバイト正規表現におけるPOSIX互換モードでの".*"扱いの不備が修正された。

 PHP4.3系列でも,大きな性能向上の可能性が報告されている。PHP6へのParott適用を提案した,前述のArntzen氏とHughes氏は,8月ころ,PHP4のスクリプト・エンジンであるZendエンジンに分岐最適化などの最適化手法を適用することにより,実行速度を大幅に高速化できることを示している。PHP4.3用の実験的なパッチが公開されており,筆者もテストを行ってみたが,ソートなどのアルゴリズム系のベンチマークで概ね2倍程度と大幅に高速化される結果が得られた。Webアプリケーションにおいてはデータベースとの通信処理などがボトルネックとなることが多いため,必ずしもこの結果が現実のWebアプリケーションが2倍高速化されることを意味するものではないが,更なる高速化の可能性を示すものとして興味深い。

 今回は,PHP5におけるオブジェクト機能強化のポイントと,その他のトピックスについて紹介した。次回以降では,引き続きPHP5の新機能や,関連するトピックスなどを順次紹介していく予定である。

廣川類(Rui Hirokawa)


■著者紹介 廣川類(ひろかわ・るい)氏
 PHPがまだPHP/FIと呼ばれていた1996年にPHPに出会い,以降,ドキュメント翻訳や国際化にかかわっている。著書に『PHP4徹底攻略』(ソフトバンクパブリッシング),『PHP4徹底攻略実戦編』(ソフトバンクパブリッシング)などがある。日本PHPユーザー会(2000年4月設立)ドキュメント部門幹事。