Só quero notar. Criei vários arquivos e se durante o processo receber algum erro, será necessário excluir os arquivos criados anteriormente. Quando arquivos criados, esqueci de usar fclose($create_file);e quando excluir, consegui Warning: unlink(created_file.xml): Permission denied in.... Portanto, para evitar esses erros, feche os arquivos criados.
Existem pelo menos duas opções disponíveis hoje em dia.
Antes de excluir a pasta, exclua todos os seus arquivos e pastas (e isso significa recursão!). Aqui está um exemplo:
publicstaticfunction deleteDir($dirPath){if(! is_dir($dirPath)){thrownewInvalidArgumentException("$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);}
E se você estiver usando o 5.2+, poderá usar um RecursiveIterator para fazer isso sem implementar a recursão:
Sua segunda implementação é um tanto perigosa: ela não verifica pontos ( .e ..) e exclui o caminho resolvido, não o caminho real.
Alix Axel
9
pequeno complemento :-) glob () não suporta arquivos como .htaccess. Eu usei a função para limpar diretórios criados pelo KCFinder (plugin CKEditor), que gera .htaccess e .thumbs (arquivo + pasta). Em vez disso, usei a scandirfunção para obter a lista de pastas. Apenas certifique-se de filtrar o '.' e '..' da lista de resultados.
Joshua - Pendo
25
DIRECTORY_SEPARATOR não é necessário quando você está criando caminhos para enviar para o sistema operacional. O Windows também aceitará barras. É principalmente útil para explode()um caminho retirado do sistema operacional. alanhogan.com/tips/php/directory-separator-not-necessary
ReactiveRaven
5
Além do @Alix Axel Usar aqui o [SplFileInfo :: getRealPath ()] ( php.net/manual/en/splfileinfo.getrealpath.php ) não é uma boa ideia. Esse método expande todos os links simbólicos, ou seja, será excluído um arquivo real de algum lugar, em vez de um link simbólico do diretório de destino. Você deve usar SplFileInfo :: getPathname ().
Vijit
2
Concordo com @Vijit, use getPathname () em vez de getRealPath (). Ele faz a mesma coisa sem excluir mais do que você espera, se forem encontrados links simbólicos.
precisa saber é o seguinte
196
Eu geralmente uso isso para excluir todos os arquivos em uma pasta:
Isso não exclui pastas recursivamente; só funciona se a pasta tiver apenas arquivos regulares, todos com extensões.
Mgnb
5
Se nenhuma recursão for necessária, esta é a melhor e mais simples resposta até agora. Obrigado!
eisbehr
2
Para remover todos os arquivos de uma pasta, não apenas os que possuem extensões, use glob da seguinte maneira: array_map('unlink', glob("$dirname/*"));Isso ainda não permite excluir diretórios aninhados na pasta.
Kremuwa # 9/18
Observe que isso também removerá arquivos de ponto (oculto).
BadHorsie 26/09/19
85
Qual é a maneira mais fácil de excluir um diretório com todos os seus arquivos?
Espero que você não esteja falando sério. O que acontece se $ dir for /
The Pixel Developer
108
@ Exatamente o mesmo que com qualquer um dos códigos acima. Não é?
Seu senso comum
7
Observe que, dependendo de como $diré gerado / fornecido, pode ser necessário fazer um pré-processamento adicional para garantir a segurança e evitar bugs. Por exemplo, se houver $dirum espaço sem escape ou ponto e vírgula, poderá haver efeitos colaterais indesejáveis. Este não é o caso das respostas que usam coisas como, rmdir()porque manipularão os caracteres especiais para você.
308 Trott
5
Versão do Windows:system('rmdir '.escapeshellarg($path).' /s /q');
Cypher
2
@ThePixelDeveloper, você não deve se preocupar em excluir /, isso só funcionaria se você lounch o script na linha de comando como raiz, porque na Web tudo acontece como usuário apache
Ben
49
Função curta que faz o trabalho:
function deleteDir($path){return is_file($path)?@unlink($path):
array_map(__FUNCTION__, glob($path.'/*'))==@rmdir($path);}
Com grande poder, vem uma grande responsabilidade : Quando você chama esta função com um valor vazio, ela exclui os arquivos iniciados em root ( /). Como salvaguarda, você pode verificar se o caminho está vazio:
function deleteDir($path){if(empty($path)){returnfalse;}return is_file($path)?@unlink($path):
array_map(__FUNCTION__, glob($path.'/*'))==@rmdir($path);}
O estático não funciona porque $ this === NULL quando você chama uma função estática em uma classe. Funcionaria se$this_func = array(__CLASS__, __FUNCTION__);
Matt Connolly
2
Alguém pode explicar a linha array_map($class_func, glob($path.'/*')) == @rmdir($path)? Eu acho que ele está recorrendo pelas subpastas, mas o que a parte == @rmdir faz? Como o <array de booleanos> == <boolean> retorna a resposta? Verifica se cada valor de retorno da recursão é igual ao booleano à direita?
arviman
2
É um truque para mesclar duas declarações em uma declaração. Isso ocorre porque os operadores ternários permitem apenas uma declaração por argumento. array_map(...)remove todos os arquivos dentro do diretório, @rmdir(...)remove o próprio diretório.
Blaise
3
Seja cuidadoso! Esta função não verifica se o caminho realmente existe. Se você passar um argumento vazio, a função começará a excluir arquivos a partir da raiz! Adicione uma verificação de integridade ao seu caminho antes de executar esta função.
Tatu Ulmanen
3
Algumas pessoas não viram o comentário de Tatu e foram excluídas recursivamente /, então anexei uma versão protegida ao meu post.
Blaise
22
Como visto no comentário mais votado na página de manual do PHP sobre rmdir()(consulte http://php.net/manual/es/function.rmdir.php ), a glob()função não retorna arquivos ocultos. scandir()é fornecido como uma alternativa que resolve esse problema.
O algoritmo descrito lá (que funcionou como um encanto no meu caso) é:
<?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);}?>
você pode explicar o is_dir ("$ dir / $ file") - não encontrou o parâmetro "$ dir / $ file"
Igor L.
O que você quer dizer? Ele verifica se a entrada encontrada em um diretório ( $file) é um diretório ou um arquivo. "$dir/$file"é o mesmo que $dir . "/" . $file.
German Latorre
Sinceramente, eu não sabia que você pode concatenar variáveis como essa :) thx
Igor L.
18
Esta é uma versão mais curta funciona muito bem para mim
No entanto, não consegui excluir algumas estruturas de diretório complexas com esse método; portanto, primeiro você deve experimentá-lo para garantir que esteja funcionando corretamente.
Eu poderia excluir a estrutura de diretórios mencionada usando uma implementação específica do Windows:
$dir = strtr($dir,'/','\\');// quotes are important, otherwise one could// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');
E apenas por uma questão de integridade, aqui está um antigo código meu:
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 my_folder_delete($path){if(!empty($path)&& is_dir($path)){
$dir =newRecursiveDirectoryIterator($path,RecursiveDirectoryIterator::SKIP_DOTS);//upper dirs are not included,otherwise DISASTER HAPPENS :)
$files =newRecursiveIteratorIterator($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 LEMBRE-SE! não passe valores vazios para nenhuma função de exclusão de diretório !!! (faça backup sempre, caso contrário, um dia você poderá sofrer um desastre!)
/*
* 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);}}}
Eu prefiro isso porque ele ainda retorna VERDADEIRO quando for bem-sucedido e FALSO quando falhar, e também evita um erro em que um caminho vazio pode tentar excluir tudo de '/ *' !!:
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);}
Quero expandir a resposta de @alcuadrado com o comentário de @Vijit para lidar com links simbólicos. Primeiro, use getRealPath (). Porém, se você tiver quaisquer links simbólicos que sejam pastas, ela falhará, pois tentará chamar o rmdir em um link - portanto, você precisará de uma verificação extra.
$it =newRecursiveDirectoryIterator($dir,RecursiveDirectoryIterator::SKIP_DOTS);
$files =newRecursiveIteratorIterator($it,RecursiveIteratorIterator::CHILD_FIRST);foreach($files as $file){if($file->isLink()){
unlink($file->getPathname());}elseif($file->isDir()){
rmdir($file->getPathname());}else{
unlink($file->getPathname());}}
rmdir($dir);
Um pouco de modificação no código do alcuadrado - globnão vejo arquivos com nome de pontos como, .htaccessentão eu uso o scandir e o script se apaga - verifique __FILE__.
function deleteDir($dirPath){if(!is_dir($dirPath)){thrownewInvalidArgumentException("$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);}
Eu normalmente gosto de adicionar uma verificação de integridade em $ cache_folder antes de executar rm -rf para evitar erros dispendiosos
glifo
1
Excluir todos os arquivos na pasta array_map('unlink', glob("$directory/*.*"));
Excluir todos. * - Arquivos na pasta (sem: "." E "..") array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Agora exclua a própria pasta rmdir($directory)
2 centavos para adicionar a ESTA resposta acima, o que é ótimo
Depois que sua função glob (ou similar) digitalizar / ler o diretório, adicione um condicional para verificar se a resposta não está vazia ou um invalid argument supplied for foreach()aviso será emitido. Assim...
if(! empty( $files )){foreach( $files as $file ){// do your stuff here...}}
Minha função completa (como um método de objeto):
privatefunction recursiveRemoveDirectory( $directory ){if(! is_dir( $directory )){thrownewInvalidArgumentException("$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()
$ directory (string) - a ser excluído recursivamente.
$ options (array) - para a remoção do diretório. As opções válidas são: traverseSymlinks: booleano, se links simbólicos para os diretórios também devem ser atravessados. O padrão falseé que significa que o conteúdo do diretório com link simbólico não seria excluído. Somente o link simbólico seria removido nesse caso padrão.
Como a solução da Playnox, mas com o elegante DirectoryIterator interno:
function delete_directory($dirPath){if(is_dir($dirPath)){
$objects=newDirectoryIterator($dirPath);foreach($objects as $object){if(!$object->isDot()){if($object->isDir()){
delete_directory($object->getPathname());}else{
unlink($object->getPathname());}}}
rmdir($dirPath);}else{thrownewException(__FUNCTION__.'(dirPath): dirPath is not a directory!');}}
fclose($create_file);
e quando excluir, conseguiWarning: unlink(created_file.xml): Permission denied in...
. Portanto, para evitar esses erros, feche os arquivos criados.Respostas:
Existem pelo menos duas opções disponíveis hoje em dia.
Antes de excluir a pasta, exclua todos os seus arquivos e pastas (e isso significa recursão!). Aqui está um exemplo:
E se você estiver usando o 5.2+, poderá usar um RecursiveIterator para fazer isso sem implementar a recursão:
fonte
.
e..
) e exclui o caminho resolvido, não o caminho real.scandir
função para obter a lista de pastas. Apenas certifique-se de filtrar o '.' e '..' da lista de resultados.explode()
um caminho retirado do sistema operacional. alanhogan.com/tips/php/directory-separator-not-necessaryEu geralmente uso isso para excluir todos os arquivos em uma pasta:
E então você pode fazer
fonte
array_map('unlink', glob("$dirname/*"));
Isso ainda não permite excluir diretórios aninhados na pasta.fonte
$dir
é gerado / fornecido, pode ser necessário fazer um pré-processamento adicional para garantir a segurança e evitar bugs. Por exemplo, se houver$dir
um espaço sem escape ou ponto e vírgula, poderá haver efeitos colaterais indesejáveis. Este não é o caso das respostas que usam coisas como,rmdir()
porque manipularão os caracteres especiais para você.system('rmdir '.escapeshellarg($path).' /s /q');
Função curta que faz o trabalho:
Eu o uso em uma classe Utils como esta:
Com grande poder, vem uma grande responsabilidade : Quando você chama esta função com um valor vazio, ela exclui os arquivos iniciados em root (
/
). Como salvaguarda, você pode verificar se o caminho está vazio:fonte
$this_func = array(__CLASS__, __FUNCTION__);
array_map($class_func, glob($path.'/*')) == @rmdir($path)
? Eu acho que ele está recorrendo pelas subpastas, mas o que a parte == @rmdir faz? Como o <array de booleanos> == <boolean> retorna a resposta? Verifica se cada valor de retorno da recursão é igual ao booleano à direita?array_map(...)
remove todos os arquivos dentro do diretório,@rmdir(...)
remove o próprio diretório./
, então anexei uma versão protegida ao meu post.Como visto no comentário mais votado na página de manual do PHP sobre
rmdir()
(consulte http://php.net/manual/es/function.rmdir.php ), aglob()
função não retorna arquivos ocultos.scandir()
é fornecido como uma alternativa que resolve esse problema.O algoritmo descrito lá (que funcionou como um encanto no meu caso) é:
fonte
$file
) é um diretório ou um arquivo."$dir/$file"
é o mesmo que$dir . "/" . $file
.Esta é uma versão mais curta funciona muito bem para mim
fonte
Você pode usar o sistema de arquivos do Symfony ( código ):
No entanto, não consegui excluir algumas estruturas de diretório complexas com esse método; portanto, primeiro você deve experimentá-lo para garantir que esteja funcionando corretamente.
Eu poderia excluir a estrutura de diretórios mencionada usando uma implementação específica do Windows:
E apenas por uma questão de integridade, aqui está um antigo código meu:
fonte
Aqui você tem uma recursão simples e agradável para excluir todos os arquivos no diretório de origem, incluindo esse diretório:
A função é baseada na recursão feita para copiar o diretório. Você pode encontrar essa função aqui: Copie todo o conteúdo de um diretório para outro usando php
fonte
A melhor solução para mim
código:
ps LEMBRE-SE!
não passe valores vazios para nenhuma função de exclusão de diretório !!! (faça backup sempre, caso contrário, um dia você poderá sofrer um desastre!)
fonte
Que tal isso:
fonte
A função Glob não retorna os arquivos ocultos; portanto, o scandir pode ser mais útil ao tentar excluir recursivamente uma árvore.
fonte
Você pode tentar da seguinte maneira:
fonte
Eu prefiro isso porque ele ainda retorna VERDADEIRO quando for bem-sucedido e FALSO quando falhar, e também evita um erro em que um caminho vazio pode tentar excluir tudo de '/ *' !!:
fonte
Quero expandir a resposta de @alcuadrado com o comentário de @Vijit para lidar com links simbólicos. Primeiro, use getRealPath (). Porém, se você tiver quaisquer links simbólicos que sejam pastas, ela falhará, pois tentará chamar o rmdir em um link - portanto, você precisará de uma verificação extra.
fonte
Usando o DirectoryIterator, o equivalente a uma resposta anterior…
fonte
Este funciona para mim:
fonte
Algo assim?
fonte
Um pouco de modificação no código do alcuadrado -
glob
não vejo arquivos com nome de pontos como,.htaccess
então eu uso o scandir e o script se apaga - verifique__FILE__
.fonte
Exemplo para o servidor Linux:
exec('rm -f -r ' . $cache_folder . '/*');
fonte
Excluir todos os arquivos na pasta
array_map('unlink', glob("$directory/*.*"));
Excluir todos. * - Arquivos na pasta (sem: "." E "..")
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Agora exclua a própria pasta
rmdir($directory)
fonte
2 centavos para adicionar a ESTA resposta acima, o que é ótimo
Depois que sua função glob (ou similar) digitalizar / ler o diretório, adicione um condicional para verificar se a resposta não está vazia ou um
invalid argument supplied for foreach()
aviso será emitido. Assim...Minha função completa (como um método de objeto):
fonte
Aqui está a solução que funciona perfeitamente:
fonte
Você pode copiar os ajudantes da YII
$ directory (string) - a ser excluído recursivamente.
$ options (array) - para a remoção do diretório. As opções válidas são: traverseSymlinks: booleano, se links simbólicos para os diretórios também devem ser atravessados. O padrão
false
é que significa que o conteúdo do diretório com link simbólico não seria excluído. Somente o link simbólico seria removido nesse caso padrão.fonte
Já experimentou o código obove em php.net
Trabalhar para mim bem
fonte
Para Windows:
fonte
Como a solução da Playnox, mas com o elegante DirectoryIterator interno:
fonte
Não me lembro de onde copiei essa função, mas parece que não está listada e está funcionando para mim
fonte
Simples e Fácil ...
fonte
Que tal isso?
Refrence: https://paulund.co.uk/php-delete-directory-and-files-in-directory
fonte
Se você não tiver certeza, determinado caminho é diretório ou arquivo, você pode usar esta função para excluir o caminho
fonte