すべてのファイルを含むディレクトリを削除する最も簡単な方法は何ですか?
フォルダを削除するために使用rmdir(PATH . '/' . $value);
していますが、その中にファイルがある場合、それを削除することはできません。
現在、利用可能なオプションは少なくとも 2 つあります。
フォルダーを削除する前に、そのすべてのファイルとフォルダーを削除します (これは再帰を意味します)。次に例を示します。
public static function deleteDir($dirPath) {
if (! is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
self::deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
また、5.2 以降を使用している場合は、再帰を自分で実装せずに RecursiveIterator を使用して実行できます。
$dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree';
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it,
RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isDir()){
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
rmdir($dir);
すべてのファイルを含むディレクトリを削除する最も簡単な方法は何ですか?
system("rm -rf ".escapeshellarg($dir));
仕事をする短い関数:
function deleteDir($path) {
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}
私はこれを次のようなUtilsクラスで使用します。
class Utils {
public static function deleteDir($path) {
$class_func = array(__CLASS__, __FUNCTION__);
return is_file($path) ?
@unlink($path) :
array_map($class_func, glob($path.'/*')) == @rmdir($path);
}
}
大きな力には大きな責任が伴います。空の値でこの関数を呼び出すと、root(/
)で始まるファイルが削除されます。安全策として、パスが空かどうかを確認できます。
function deleteDir($path) {
if (empty($path)) {
return false;
}
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}
PHP マニュアル ページrmdir()
( http://php.net/manual/es/function.rmdir.phpを参照) に関する最も投票されたコメントに見られるように、glob()
関数は隠しファイルを返しません。 scandir()
その問題を解決する代替手段として提供されています。
そこに記載されているアルゴリズム(私の場合は魅力的に機能しました)は次のとおりです。
<?php
function delTree($dir)
{
$files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>
Symfony のファイルシステム( code ) を使用できます:
// composer require symfony/filesystem
use Symfony\Component\Filesystem\Filesystem;
(new Filesystem)->remove($dir);
ただし、この方法では一部の複雑なディレクトリ構造を削除できませんでした。そのため、最初に試して、正しく機能することを確認してください。
Windows 固有の実装を使用して、上記のディレクトリ構造を削除できます。
$dir = strtr($dir, '/', '\\');
// quotes are important, otherwise one could
// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');
完全を期すために、ここに私の古いコードを示します。
function xrmdir($dir) {
$items = scandir($dir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir.'/'.$item;
if (is_dir($path)) {
xrmdir($path);
} else {
unlink($path);
}
}
rmdir($dir);
}
これは短いバージョンです
function deleteDirectory($dirPath) {
if (is_dir($dirPath)) {
$objects = scandir($dirPath);
foreach ($objects as $object) {
if ($object != "." && $object !="..") {
if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") {
deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object);
} else {
unlink($dirPath . DIRECTORY_SEPARATOR . $object);
}
}
}
reset($objects);
rmdir($dirPath);
}
}
ここでは、そのディレクトリを含むソース ディレクトリ内のすべてのファイルを削除するための 1 つの素晴らしく単純な再帰があります。
function delete_dir($src) {
$dir = opendir($src);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
delete_dir($src . '/' . $file);
}
else {
unlink($src . '/' . $file);
}
}
}
closedir($dir);
rmdir($src);
}
関数は、ディレクトリをコピーするために行われる再帰に基づいています。ここでその機能を見つけることができます: Copy whole contents of a directory to another using php
次のように試すことができます。
/*
* Remove the directory and its content (all files and subdirectories).
* @param string $dir the directory name
*/
function rmrf($dir) {
foreach (glob($dir) as $file) {
if (is_dir($file)) {
rmrf("$file/*");
rmdir($file);
} else {
unlink($file);
}
}
}
私にとってのベストソリューション
my_folder_delete("../path/folder");
コード:
function my_folder_delete($path) {
if(!empty($path) && is_dir($path) ){
$dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :)
$files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path);
}
}
ps覚えておいてください!
ディレクトリ削除関数に EMPTY VALUES を渡さないでください!!! (常にバックアップしてください。そうしないと、いつか災害が発生する可能性があります!!)
これはどうですか:
function recursiveDelete($dirPath, $deleteParent = true){
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
}
if($deleteParent) rmdir($dirPath);
}
glob 関数は隠しファイルを返さないため、ツリーを再帰的に削除しようとする場合は scandir がより便利です。
<?php
public static function delTree($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>
シンボリックリンクの処理に関する@Vijitのコメントで@alcuadradoの回答を拡張したいと思います。まず、getRealPath() を使用します。ただし、フォルダーであるシンボリックリンクがある場合、リンクで rmdir を呼び出そうとするため失敗します。そのため、追加のチェックが必要です。
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isLink()) {
unlink($file->getPathname());
} else if ($file->isDir()){
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
rmdir($dir);
成功するとTRUEを返し、失敗するとFALSEを返すので、これが好きです。また、空のパスが'/ *'からすべてを削除しようとするバグを防ぎます!!:
function deleteDir($path)
{
return !empty($path) && is_file($path) ?
@unlink($path) :
(array_reduce(glob($path.'/*'), function ($r, $i) { return $r && deleteDir($i); }, TRUE)) && @rmdir($path);
}
以前の回答と同等の DirectoryIterator を使用する…</p>
function deleteFolder($rootPath)
{
foreach(new DirectoryIterator($rootPath) as $fileToDelete)
{
if($fileToDelete->isDot()) continue;
if ($fileToDelete->isFile())
unlink($fileToDelete->getPathName());
if ($fileToDelete->isDir())
deleteFolder($fileToDelete->getPathName());
}
rmdir($rootPath);
}
このようなもの?
function delete_folder($folder) {
$glob = glob($folder);
foreach ($glob as $g) {
if (!is_dir($g)) {
unlink($g);
} else {
delete_folder("$g/*");
rmdir($g);
}
}
}
フォルダー内のすべてのファイルを
array_map('unlink', glob("$directory/*.*"));
削除する フォルダー内のすべての .*-ファイルを削除する ("." および ".." を除く)
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
フォルダー自体を削除する
rmdir($directory)
完璧に機能するソリューションは次のとおりです。
function unlink_r($from) {
if (!file_exists($from)) {return false;}
$dir = opendir($from);
while (false !== ($file = readdir($dir))) {
if ($file == '.' OR $file == '..') {continue;}
if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
unlink_r($from . DIRECTORY_SEPARATOR . $file);
}
else {
unlink($from . DIRECTORY_SEPARATOR . $file);
}
}
rmdir($from);
closedir($dir);
return true;
}
シンプルで簡単...
$dir ='pathtodir';
if (is_dir($dir)) {
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if ($filename->isDir()) continue;
unlink($filename);
}
rmdir($dir);
}
Playnox のソリューションに似ていますが、エレガントな組み込みの DirectoryIterator を使用します。
function delete_directory($dirPath){
if(is_dir($dirPath)){
$objects=new DirectoryIterator($dirPath);
foreach ($objects as $object){
if(!$object->isDot()){
if($object->isDir()){
delete_directory($object->getPathname());
}else{
unlink($object->getPathname());
}
}
}
rmdir($dirPath);
}else{
throw new Exception(__FUNCTION__.'(dirPath): dirPath is not a directory!');
}
}
<?php
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir")
rrmdir($dir."/".$object);
else unlink ($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
?>
php.net の obove コードを試してみてください。
私のためにうまく働いてください
Windows の場合:
system("rmdir ".escapeshellarg($path) . " /s /q");
この関数をどこからコピーしたかは覚えていませんが、リストされていないようで、機能しているようです
function rm_rf($path) {
if (@is_dir($path) && is_writable($path)) {
$dp = opendir($path);
while ($ent = readdir($dp)) {
if ($ent == '.' || $ent == '..') {
continue;
}
$file = $path . DIRECTORY_SEPARATOR . $ent;
if (@is_dir($file)) {
rm_rf($file);
} elseif (is_writable($file)) {
unlink($file);
} else {
echo $file . "is not writable and cannot be removed. Please fix the permission or select a new path.\n";
}
}
closedir($dp);
return rmdir($path);
} else {
return @unlink($path);
}
}
ここに簡単な解決策があります
$dirname = $_POST['d'];
$folder_handler = dir($dirname);
while ($file = $folder_handler->read()) {
if ($file == "." || $file == "..")
continue;
unlink($dirname.'/'.$file);
}
$folder_handler->close();
rmdir($dirname);