不正なハンドラがreaddir()に渡されたときの返り値がPHP5.2と5.3で異なり下手すると無限ループする(というか、した)でござる
<?php $handle = opendir('/path/to/dir'); while (false !== ($file = readdir($handle))) { $files[] = $file; }
上記のようにopendir()でディレクトリハンドラを開き、readdir()に渡して/path/to/dir内のファイル名を$filesにpushするような処理があるとします。
本来これは作法の悪いソースで、ループさせる前にopendir()の返り値がfalseでないかチェックする必要があります。
<?php if ($handle = opendir('/path/to/dir')) { while (false !== ($file = readdir($handle))) { $files[] = $file; } }
しかしPHP5.2の場合、万が一/path/to/dirが開けなくてもreaddir()がfalseを返すため、ループは行なわれません。
$ php -r "var_dump(readdir(opendir(NULL)));" PHP Warning: readdir(): supplied argument is not a valid Directory resource in Command line code on line 1 bool(false)
(上記はPHP Version => 5.2.6環境)
しかし、PHP5.3から/path/to/dirが開けなかった場合、readdir()はNULLを返すようになりました。
そのため上記のようなソースではfalse !== NULLが真となり無限ループに落ち入ります。
$ php -r "var_dump(readdir(opendir(NULL)));" PHP Warning: readdir() expects parameter 1 to be resource, boolean given in Command line code on line 1 PHP Stack trace: PHP 1. {main}() Command line code:0 NULL // NULLが返ってくる
(上記はPHP Version => 5.3.4環境)
PHP5.2以前の時代のソースを5.3環境で利用する場合はご注意ください。
謝辞
社長++