konekto Inc with PHP , MySQL コネクト株式会社 技術情報コンテンツ


Tips

PHP 4.3.10にアップグレードしたら…

「PHP 4.3.10にアップグレードした途端、foreach文でエラーになってしまう」

掲示板やメーリングリストで、このような話題が上がっているのを見た事は無いだろうか。 また、このトラブルの回避方法として、Zend OptimizerなどPHPスクリプトの高速化を行うモジュールをアンインストールする事を勧める人も少なくない。

果たして、正常に動作させるためには高速化を諦めなければならないのだろうか。 また、今回のトラブルの原因は一体何であろうか。

トラブルの原因

PHPの動作原理を理解する

PHPは、テキストファイルに記述されたスクリプトをコンパイルしながら実行するインタプリタ言語である。

インタプリタ言語といえば、黎明期は逐次コンパイルと同時にスクリプトを実行する方式が主流であったが、現在では全てコンパイルした後で実行する方式が主流である。 コンパイル結果は、VM*1が使用するOPコード*2になってメモリ上に蓄えられている。

PHPの実行速度を高速化する場合、このOPコードをキャッシュしてしまうアプローチ*3と、OPコードの内容を見直して最適化するアプローチ*4の2つのアプローチが存在する。

前者は最も単純なアプローチであり、PHPのバージョンによって大きく影響する事は少ない。 大きな影響を受けるのは、後者のアプローチである。

PHP 4.3.10で変更されたこと

コンパイラは、PHPスクリプトを解釈した結果をOPコードとして管理している。 つまり、どの関数や演算からどのようなOPコードが発生しても、コンパイラとVMの間で互換性が取れていれば、必ず正常に動作する。

PHPの場合、コンパイラとVMは一緒にバージョンアップされて、1つのパッケージとしてリリースされるため、両者の間にOPコードの互換性による問題が発生する事は有り得ない。

PHP 4.3.10では、幾つかのバグフィックスと同時に、パフォーマンス改善の目的でforeach関数の処理が大きく変更されている。 これに伴い、内部的な動作だけではなくOPコードも変更されている。

なぜ高速化モジュールがトラブルの原因になるのか

前述の通り、コンパイラとVMとの互換性が保たれているのに、高速化モジュールを組み込むとトラブルが発生するのだろうか。 その原因は、最適化のアルゴリズムにある。

コンパイラによって生成されたOPコードは、単純にコンパイルした結果に過ぎないので、無駄な処理も多く含まれている。 この無駄な部分を省く事で高速化が望める。 また、コンパイル結果のうち特定の処理に関するOPコードを、最適なアルゴリズムのOPコードに置き換えることで、更なる高速化が望める。 こういった地道なチューニングが、パフォーマンス向上に繋がっていく。

今回の場合、foreach関数に関するOPコードがPHP 4.3.10になって変更されてしまった事で、高速化モジュールとの間に不整合が発生してしまったのだ。

トラブルを回避するには

掲示板などで発言されている通り、高速化モジュールをアンインストールするという方法もある。 しかし、これでは、パフォーマンスが低下し、Webサーバの負荷を増加させてしまう事に繋がるので得策ではない。

一番良い方法は、最新版の高速化モジュールを導入する事である。
少なくとも、Zend Optimizerに関しては、最新版である Zend Optimizer 2.5.7 で解消されている。 Zend Optimizer をインストールしている人は、最新版にアップグレードする事を強く推奨する。

他の高速化モジュールについては、PHP 4.3.10 をサポートしていない可能性も考えられるので、それぞれの公式サイトでのアナウンスを確認して頂けると幸いである。

補足事項

ゼンド製品のうち、Zend Optimizerがバンドルされている製品を利用されている場合は、速やかにZend Optimizer 2.5.7にアップグレードをする必要があります。

該当製品は次の通りです。

  • Zend Optimizer(2.5.7未満)
  • Zend Studio(Zend Studio Serverを導入している場合)
  • Zend Accelerator
  • Zend Performance Suite

次の方法で、Zend Optimizerがインストールされているかを確認する事が可能です。

下記のスクリプトをウェブサーバの公開ディレクトリ上に用意し、ウェブブラウザでアクセスを行って下さい。

<?php
phpinfo();
?>

ウェブブラウザには、サーバにインストールされているPHPおよび拡張モジュールの情報が表示されます。 その中に、次のようなメッセージが含まれていると、Zend Optimizerがインストールされている事になります。

With Zend Optimizer 2.X.X

"Zend Optimizer"の後に続く数字が、"2.5.7"ではない場合、最新版のZend Optimizer(バージョン2.5.7)をダウンロードし、インストール作業を行って下さい。

詳しくは、既知の問題と対応策をご覧下さい。


*1 Virtual Machine=仮想マシン。ソフトウェア上で動作する仮想的な実行環境。PCの中でもう1台のPCが動作していると考えて差し支えない。
*2 オペコード。中間コードとも呼ばれる。VMで使用する機械語と考えて差し支えない。
*3 Zend AccelaratorPHP AccelaratorAPCなど
*4 Zend OptimizerionCubeローダーなど

最終更新のRSS