PHP の再帰によりメモリ不足が発生する

WBOY
リリース: 2016-06-23 13:53:47
オリジナル
1427 人が閲覧しました

$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');
ログイン後にコピー

上記のコードの主な機能は、ディレクトリ K:/project/fileOperate 内のすべてのファイルとサブフォルダーをデータベースに書き込むことですが、この再帰は大量のリソースを消費し、1G を超えるメモリを占有します。私の何が間違っているのか聞きたいのですが?それとももっと良い方法があるのでしょうか?


ディスカッションへの返信 (解決策)

ここで前の xu モデレーターからメソッドを借用しましょう

$res=glob($dir); for($i=0;$i if(is_dir($res[$i])){
$res=array_merge($res,glob($res[$i] ].'/*'));
$g=glob($res[$i].'/*');
}
}
?> ( $filename == '.' || $filename == '..') コメントアウトしますか?

$filename = '.' および $filename = '..' の場合、 is_dir(realpath($dir.'/'.$filename) が成立すると、無限ループが発生しませんか?

実際、 glob 関数またはディレクトリイテレータははるかに単純です

mysql の挿入操作のため、ここでの再帰のメモリ消費は深刻になるはずです

if ($filename == '.' | | $filename == '..') continue; ステートメントは必須です。そうでない場合は、無限ループになります。

PHP に付属の SPL ライブラリを使用すると、はるかに高速になります。たとえば、

$iterator = new RecursiveIteratorIterator() new RecursiveDirectoryIterator('./'));

foreach ($iterator as $it){

echo $it->getFilename(),'->',$it->getSize(),'
';

}

SPL はまだ適切にパッケージ化されているので、マニュアルを参照することができます

memory_get_peak_usage
この関数を使用して、断片化されたファイルでいっぱいの 8.4G D 上で実行される空のスクリプトとコードをテストしました。ディスク、結果はほぼ同じです
ちょっと混乱しています

1Gは怖すぎるので、作者は他の方法を考えるべきです

LZのコードに何か問題があるような気がしますかどうかの判定を追加する必要があります。は現在のディレクトリと上位ディレクトリです。この方法では、それほど多くのメモリを消費することはありません

if ($filename == '.' || $filename == '..') continue; これを追加する必要があります。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート