残り一年! PHP4からPHP5への移行

第2回 PHP4.4以前からの移行とPHP5におけるオブジェクトの仕様変更

この記事を読むのに必要な時間:およそ 4.5 分

PHPバイナリの名前

前回も紹介しましたが古いPHPではCGI用のバイナリが「php」から「php-cgi」に変更されています。CGIバイナリの名前を「php」に変更しても動作しますが,新しい名前でCGIを正常に動作させるにはWebサーバの設定ファイルの変更が必要となります。

長い名前のシステム定義配列

最近のPHPアプリケーションでは見かけなくなりましたが,$HTTP_POST_VARS,$HTTP_GET_VERSなどのPHPが定義する配列変数はphp.iniで初期化しないように設定できるようになっています。デフォルトで初期化されるように設定されているのでこれらの長い名前のシステム定義配列が初期化されないケースはあまりないと思いますが,もしこれらの配列が未定義の場合はphp.ini設定を変更します。

register_long_arrays=on

をphp.iniに追加します。Apacheであれば.htaccessからも変更できます。

register_globals=off

register_globalsのデフォルト設定がoffに変更されたのはPHP 4.2.0からなので,最近のアプリケーションではregister_globals=onを前提とするアプリケーションはほとんど見かけなくなりました。しかし,アプリケーションの中にはregister_globals=onを前提としているものもあります。PHPをサポートするホスティングサービスで新しいPHPを提供していても,アプリケーションの互換性のためにregister_globals=onをデフォルトに設定している会社も少なくありません。

アプリケーションがregister_globals=onを前提としているためやむを得ずresgister_globals=onに設定する場合は,安全性に注意してください。

参照カウンタの32ビット化

PHP4からPHP5へ移行する場合の注意点ではありませんが,動作が変わるのでこの仕様変更を紹介します。PHP5.0.0から変数の参照カウンタが16ビットから32ビットに拡張されました。この拡張は移行時に問題を発生することはありませんが,PHP4ではクラッシュしていたプログラムがPHP5から正常に動作する場合があります。

例:PHP4でクラッシュしPHP5では問題なく実行されるコード

<?php
$max = 1 << 16;
$v = 123;
for ($i = 1; $i < $max; $i++) {
  $arr[] = &$v;
}

echo $v;
?>

例:PHP4(Linux環境)での実行例

[yohgaki@dev php4-php5-migration]$ ./php4 reference_counter.php
123
*** glibc detected *** /usr/local/php-4.4.7/bin/php: free(): invalid next size (fast): 0x09029b78 ***
======= Backtrace: =========
/lib/libc.so.6[0x79c211]
/lib/libc.so.6(__libc_free+0x83)[0x79d863]
/usr/local/php-4.4.7/bin/php(shutdown_memory_manager+0x82)[0x8162142]
/usr/local/php-4.4.7/bin/php(php_request_shutdown+0x2f7)[0x8143b67]
/usr/local/php-4.4.7/bin/php(main+0x3b9)[0x818bbf9]
/lib/libc.so.6(__libc_start_main+0xdc)[0x75074c]
/usr/local/php-4.4.7/bin/php(gdImageCreateFromPngCtx+0x145)[0x806d5b1]

例:PHP5(Linux環境)での実行例

[yohgaki@dev php4-php5-migration]$ ./php5 reference_counter.php
123

PHP4ではメモリエラーでクラッシュしていることが分かります。PHPがクラッシュするとWeb環境ではページに何も表示されずログにもなにも記録されていない場合がほとんどです。Web環境でクラッシュを検出するにはgdbなどのデバッガを利用できますが,このクラッシュはメモリマネージャでエラーが発生していることが分かります。大きいアプリケーションの場合,クラッシュの原因となるコードがどこなのか特定する作業は困難です。

PHP5に移行することにより参照カウンタのオーバーフローによる原因不明のクラッシュで悩まされることはなくなると思います。

著者プロフィール

大垣靖男(おおがきやすお)

University of Denver卒。同校にてコンピュータサイエンスとビジネスを学ぶ。株式会社シーエーシーを経て,エレクトロニック・サービス・イニシアチブ有限会社を設立。
オープンソース製品は比較的古くから利用し,Linuxは0.9xのころから利用している。オープンソースシステム開発への参加はエレクトロニック・サービス・イニシアチブ設立後から。PHPプロジェクトでは,PostgreSQLモジュールのメンテナンスを担当している。

URLhttp://blog.ohgaki.net/

著書