ホームページ >バックエンド開発 >PHPチュートリアル >PHP の再帰によりメモリ不足が発生する
$user = 'root';$pass = 'thrope';$dbh = new PDO('mysql:host=localhost;dbname=income', $user, $pass);$query = 'insert into picinfo set picpath=:pp, picsize=:ps';//把文件路径和文件大小写入数据库$stmt = $dbh->prepare($query);function dir_read($dir){ $dh = opendir($dir);//if (is_dir($dir)) echo realpath($dir).'<br/>'; while (false !== ($filename = readdir($dh))){//echo realpath($dir.'/'.$filename).'<br/>'; //if ($filename == '.' || $filename == '..') continue; if (is_file($dir.'/'.$filename)){ global $stmt; $stmt->execute(array(':pp'=>realpath($dir.'/'.$filename), ':ps'=>filesize(realpath($dir.'/'.$filename)))); //echo $dbh->errorCode(); } if (is_dir(realpath($dir.'/'.$filename)))//这个递归调用特别耗费资源 dir_read(realpath($dir.'/'.$filename)); } closedir($dh);}dir_read('K:/project/fileOperate');
d1209a7e29829c6d8a09ffa4efc4debe ( $filename == '.' || $filename == '..') コメントアウトしますか?
$filename = '.' および $filename = '..' の場合、 is_dir(realpath($dir.'/'.$filename) が成立すると、無限ループが発生しませんか?
実際、 glob 関数またはディレクトリイテレータははるかに単純です
mysql の挿入操作のため、ここでの再帰のメモリ消費は深刻になるはずです
if ($filename == '.' | | $filename == '..') continue; ステートメントは必須です。そうでない場合は、無限ループになります。
PHP に付属の SPL ライブラリを使用すると、はるかに高速になります。たとえば、
foreach ($iterator as $it){
echo $it->getFilename(),'->',$it->getSize(),'3758937f2e19267c4b26eb8fbb84b4a2';}
SPL はまだ適切にパッケージ化されているので、マニュアルを参照することができます
memory_get_peak_usage
この関数を使用して、断片化されたファイルでいっぱいの 8.4G D 上で実行される空のスクリプトとコードをテストしました。ディスク、結果はほぼ同じです
ちょっと混乱しています
1Gは怖すぎるので、作者は他の方法を考えるべきです
LZのコードに何か問題があるような気がしますかどうかの判定を追加する必要があります。は現在のディレクトリと上位ディレクトリです。この方法では、それほど多くのメモリを消費することはありません
if ($filename == '.' || $filename == '..') continue; これを追加する必要があります。