web-dev-qa-db-ja.com

PHPの再帰的なディレクトリ削除関数ですか?

PHPを使用して画像サブフォルダのコンテンツを移動しています

GalleryName/images /

別のフォルダに。移動後、GalleryNameディレクトリおよびその中のその他すべてを削除する必要があります。

ディレクトリが空でない限り、rmdir()は機能しないことを知っています。上から始めてscandir()への再帰関数を作成し、次にファイルである場合はunlink()、ディレクトリである場合はscandir()を構築するのにしばらく時間を費やしましたが、次に、rmdir()に進むと、各空のディレクトリが表示されます。

これまでのところ、正しく機能しておらず、私は考え始めましたこれは、PHPで実行できるはずです)とんでもないほど単純な関数ではありませんか?ディレクトリの削除?

それで私が見逃しているものはありますか?または、少なくともこのアクションに使用される実績のある機能はありますか?

任意の助けいただければ幸いです。

ここではphp.netサイトのコメントよりも信頼しています-何百もの関数がありますが、ここで誰かが他の関数よりも優れているかどうか知りたいです。

26
rhodesjason

これはどうですか?

foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
        $path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname());
}
rmdir($dirPath);
88
barbushin

これは私が作成/変更した再帰的な関数で、最終的には機能しているようです。うまくいけば、そこにはあまり危険なものはありません。

function destroy_dir($dir) { 
    if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
    foreach (scandir($dir) as $file) { 
        if ($file == '.' || $file == '..') continue; 
        if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) { 
            chmod($dir . DIRECTORY_SEPARATOR . $file, 0777); 
            if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) return false; 
        }; 
    } 
    return rmdir($dir); 
} 
14
rhodesjason

アプリケーションのサーバーがLinuxを実行している場合は、Shell_exec()関数を使用して、次のようにrm -Rコマンドを指定します。

    $realPath = realpath($dir_path);

    if($realPath === FALSE){
         throw new \Exception('Directory does not exist');
    }

    Shell_exec("rm ". escapeshellarg($realPath) ." -R");

説明:

パスが存在する場合にのみ指定されたディレクトリを再帰的に削除し、パスをエスケープして、シェルコマンドインジェクションを回避するためのシェル引数としてのみ使用できるようにします。

escapeshellargを使用しない場合は、コマンドの後に削除するディレクトリに名前を付けることでコマンドを実行できます。

2
Gabriel Guelfi

非表示のUNIXファイルをドットプレフィックスで処理し、グロブを使用する関数を適応させました。

public static function deleteDir($path) {
    if (!is_dir($path)) {
        throw new InvalidArgumentException("$path is not a directory");
    }
    if (substr($path, strlen($path) - 1, 1) != '/') {
        $path .= '/';
    }
    $dotfiles = glob($path . '.*', GLOB_MARK);
    $files = glob($path . '*', GLOB_MARK);
    $files = array_merge($files, $dotfiles);
    foreach ($files as $file) {
        if (basename($file) == '.' || basename($file) == '..') {
            continue;
        } else if (is_dir($file)) {
            self::deleteDir($file);
        } else {
            unlink($file);
        }
    }
    rmdir($path);
}
0
Aram Kocharyan
public static function rrmdir($dir)
{
    if (is_dir($dir)) {
        $files = scandir($dir);
        foreach ($files as $file) {
            if ($file != "." && $file != "..") {
                if (filetype($dir . "/" . $file) == "dir")
                    self::rrmdir($dir . "/" . $file);
                else
                    unlink($dir . "/" . $file);
            }
        }
        reset($files);
        rmdir($dir);
    }
}
0
yousef

ここにさらに例のある別のスレッドがあります: PHPでディレクトリとその内容全体(ファイル+サブディレクトリ)を再帰的に削除するにはどうすればよいですか?

Yiiを使用している場合は、フレームワークに任せることができます。

CFileHelper::removeDirectory($my_directory);
0
David Newcomb

私はphpのヘルプページから派生した拡張メソッドを好む http://php.net/manual/en/function.rmdir.php#115598

 // check accidential empty, root or relative pathes
 if (!empty($path) && ...)
 {
  if (PHP_OS === 'Windows')
  {
    exec('rd /s /q "'.$path.'"');
  }
  else
  {
      exec('rm -rf "'.$path.'"');
  }
}
else
{
    error_log('path not valid:$path'.var_export($path, true));
}

私の決定の理由:

  • 速度
  • 単純にする
0
user1680948