모든 파일이 들어있는 디렉토리를 삭제하는 가장 쉬운 방법은 무엇입니까?
rmdir(PATH . '/' . $value);
폴더를 삭제하는 데 사용 하고 있지만 폴더 안에 파일이 있으면 삭제할 수 없습니다.
fclose($create_file);
삭제 할 때 얻었습니다 Warning: unlink(created_file.xml): Permission denied in...
. 따라서 이러한 오류를 피하려면 작성된 파일을 닫아야합니다.
모든 파일이 들어있는 디렉토리를 삭제하는 가장 쉬운 방법은 무엇입니까?
rmdir(PATH . '/' . $value);
폴더를 삭제하는 데 사용 하고 있지만 폴더 안에 파일이 있으면 삭제할 수 없습니다.
fclose($create_file);
삭제 할 때 얻었습니다 Warning: unlink(created_file.xml): Permission denied in...
. 따라서 이러한 오류를 피하려면 작성된 파일을 닫아야합니다.
답변:
요즘에는 두 가지 이상의 옵션이 있습니다.
폴더를 삭제하기 전에 모든 파일과 폴더를 삭제하십시오 (이것은 재귀를 의미합니다!). 예를 들면 다음과 같습니다.
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);
.
및 ..
)을 확인하지 않고 실제 경로가 아닌 해결 된 경로를 삭제합니다.
scandir
폴더 목록을 가져 오기 위해 함수를 사용했습니다 . '.'을 필터링하십시오. 및 결과 목록에서 '..'파일.
explode()
가져온 경로 를 ing하는 데 유용합니다 . alanhogan.com/tips/php/directory-separator-not-recessary
나는 일반적으로 이것을 사용하여 폴더의 모든 파일을 삭제합니다.
array_map('unlink', glob("$dirname/*.*"));
그리고 당신은 할 수 있습니다
rmdir($dirname);
array_map('unlink', glob("$dirname/*"));
그래도 폴더에 중첩 된 디렉토리는 삭제할 수 없습니다.
파일이 들어있는 디렉토리를 삭제하는 가장 쉬운 방법은 무엇입니까?
system("rm -rf ".escapeshellarg($dir));
$dir
생성 / 제공 방법에 따라 안전하고 버그를 피하기 위해 추가 사전 처리를 수행해야 할 수도 있습니다. 예를 들어, $dir
이스케이프되지 않은 공간이나 세미콜론이 있으면 바람직하지 않은 부작용이있을 수 있습니다. rmdir()
특수 문자를 처리하기 때문에 이와 같은 답변을 사용하는 경우에는 그렇지 않습니다 .
system('rmdir '.escapeshellarg($path).' /s /q');
일을하는 짧은 기능 :
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);
}
}
큰 힘을 가지고 큰 책임을집니다 . 빈 값으로이 함수를 호출하면 루트 ( /
)로 시작하는 파일이 삭제됩니다 . 안전을 위해 경로가 비어 있는지 확인할 수 있습니다.
function deleteDir($path) {
if (empty($path)) {
return false;
}
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}
$this_func = array(__CLASS__, __FUNCTION__);
array_map($class_func, glob($path.'/*')) == @rmdir($path)
? 나는 그가 하위 폴더를 통해 재귀하고 있다고 생각하지만 == @rmdir 부분은 무엇을합니까? <부울 배열> == <부울>은 어떻게 대답을 반환합니까? 재귀의 각 반환 값이 오른쪽의 부울과 같은지 확인합니까?
array_map(...)
디렉토리 내의 모든 파일을 @rmdir(...)
제거하고 디렉토리 자체를 제거합니다.
/
했기 때문에 게시물에 보호 버전을 추가했습니다.
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);
}
?>
$file
) 에있는 항목 이 디렉토리인지 파일인지 확인합니다. "$dir/$file"
와 동일합니다 $dir . "/" . $file
.
이것은 짧은 버전입니다 나에게 잘 작동합니다
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);
}
}
Symfony 's Filesystem ( 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 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);
}
기능은 디렉토리 복사를 위해 만들어진 재귀를 기반으로합니다. 해당 기능을 여기에서 찾을 수 있습니다 : PHP를 사용하여 디렉토리의 전체 내용을 다른 디렉토리로 복사 하십시오.
나를위한 최고의 솔루션
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);
}
}
추억!
비어있는 값을 모든 디렉토리 삭제 기능에 전달하지 마십시오 !!! (항상 백업하십시오. 그렇지 않으면 언젠가는 재난을 겪을 수 있습니다!)
이건 어때?
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);
}
?>
나는 이것이 성공하면 여전히 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);
}
@aljiadrado의 답변을 @Vijit의 심볼릭 링크 처리와 함께 확장하고 싶습니다. 먼저 getRealPath ()를 사용하십시오. 그러나 폴더 인 symlinks가 있으면 링크에서 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);
이전 답변과 동등한 DirectoryIterator 사용…
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);
}
alcuadrado 코드의 작은 비트 수정- glob
같은 이름의 파일이 표시되지 않으므로 .htaccess
scandir을 사용하고 스크립트는 자체 검사를 삭제합니다 __FILE__
.
function deleteDir($dirPath) {
if (!is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = scandir($dirPath);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
if (is_dir($dirPath.$file)) {
deleteDir($dirPath.$file);
} else {
if ($dirPath.$file !== __FILE__) {
unlink($dirPath.$file);
}
}
}
rmdir($dirPath);
}
Linux 서버의 예 : exec('rm -f -r ' . $cache_folder . '/*');
위의 답변 에 추가 할 2 센트 , 이는 훌륭한 BTW입니다
glob (또는 이와 유사한) 기능이 디렉토리를 스캔 / 읽은 후 응답이 비어 있지 않은지 확인하기위한 조건을 추가하거나 invalid argument supplied for foreach()
경고가 발생합니다. 그래서...
if( ! empty( $files ) )
{
foreach( $files as $file )
{
// do your stuff here...
}
}
내 전체 기능 (객체 방법으로) :
private function recursiveRemoveDirectory( $directory )
{
if( ! is_dir( $directory ) )
{
throw new InvalidArgumentException( "$directory must be a directory" );
}
if( substr( $directory, strlen( $directory ) - 1, 1 ) != '/' )
{
$directory .= '/';
}
$files = glob( $directory . "*" );
if( ! empty( $files ) )
{
foreach( $files as $file )
{
if( is_dir( $file ) )
{
$this->recursiveRemoveDirectory( $file );
}
else
{
unlink( $file );
}
}
}
rmdir( $directory );
} // END recursiveRemoveDirectory()
완벽하게 작동하는 솔루션은 다음과 같습니다.
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;
}
YII 도우미를 복사 할 수 있습니다
$ directory (string)-재귀 적으로 삭제됩니다.
$ options (배열)-디렉토리 제거 용. 유효한 옵션은 다음과 같습니다. traverseSymlinks : 부울, 디렉토리에 대한 symlink도 순회해야하는지 여부. 기본값은 false
이며 심볼릭 링크 된 디렉토리의 내용은 삭제되지 않습니다. 해당 기본 경우에는 symlink 만 제거됩니다.
public static function removeDirectory($directory,$options=array())
{
if(!isset($options['traverseSymlinks']))
$options['traverseSymlinks']=false;
$items=glob($directory.DIRECTORY_SEPARATOR.'{,.}*',GLOB_MARK | GLOB_BRACE);
foreach($items as $item)
{
if(basename($item)=='.' || basename($item)=='..')
continue;
if(substr($item,-1)==DIRECTORY_SEPARATOR)
{
if(!$options['traverseSymlinks'] && is_link(rtrim($item,DIRECTORY_SEPARATOR)))
unlink(rtrim($item,DIRECTORY_SEPARATOR));
else
self::removeDirectory($item,$options);
}
else
unlink($item);
}
if(is_dir($directory=rtrim($directory,'\\/')))
{
if(is_link($directory))
unlink($directory);
else
rmdir($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에서 순종 코드를 사용해보십시오.
나를 위해 잘 작동
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!');
}
}
이 함수를 어디에서 복사했는지 기억이 나지 않지만 목록에없는 것처럼 보이고 작동합니다.
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);
}
}
이건 어때?
function Delete_Directory($Dir)
{
if(is_dir($Dir))
{
$files = glob( $Dir . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
Delete_Directory( $file );
}
if(file_exists($Dir))
{
rmdir($Dir);
}
}
elseif(is_file($Dir))
{
unlink( $Dir );
}
}
참조 : https://paulund.co.uk/php-delete-directory-and-files-in-directory
확실하지 않은 경우 주어진 경로는 디렉토리 또는 파일입니다.이 기능을 사용하여 경로를 삭제할 수 있습니다
function deletePath($path) {
if(is_file($path)){
unlink($path);
} elseif(is_dir($path)){
$path = (substr($path, -1) !== DIRECTORY_SEPARATOR) ? $path . DIRECTORY_SEPARATOR : $path;
$files = glob($path . '*');
foreach ($files as $file) {
deleteDirPath($file);
}
rmdir($path);
} else {
return false;
}
}