PHP: отсоединить все файлы в каталоге, а затем удалить этот каталог
Есть ли способ, которым я могу использовать поиск по RegExp или Wildcard, чтобы быстро удалить все файлы в папке, а затем удалить эту папку в PHP, БЕЗ с помощью команды "exec"? Мой сервер не дает мне права использовать эту команду. Простая петля некоторого вида была бы достаточна.
Мне нужно что-то, что будет соответствовать логике следующего утверждения, но, очевидно, будет действительным:
$dir = "/home/dir"
unlink($dir . "/*"); # "*" being a match for all strings
rmdir($dir);
9 ответов
Использование glob
найти все файлы, соответствующие шаблону.
function recursiveRemoveDirectory($directory)
{
foreach(glob("{$directory}/*") as $file)
{
if(is_dir($file)) {
recursiveRemoveDirectory($file);
} else {
unlink($file);
}
}
rmdir($directory);
}
Использование glob()
чтобы легко перебрать каталог, чтобы удалить файлы, то вы можете удалить каталог.
foreach (glob($dir."/*.*") as $filename) {
if (is_file($filename)) {
unlink($filename);
}
}
rmdir($dir);
glob()
Функция делает то, что вы ищете. Если вы используете PHP 5.3+, вы можете сделать что-то вроде этого:
$dir = ...
array_walk(glob($dir . '/*'), function ($fn) {
if (is_file($fn))
unlink($fn);
});
unlink($dir);
Простой и эффективный способ рекурсивного удаления всех файлов и папок с помощью стандартной библиотеки PHP, а именно RecursiveIteratorIterator и RecursiveDirectoryIterator. Дело в том, RecursiveIteratorIterator::CHILD_FIRST
флаг, итератор будет сначала перебирать файлы, а каталог - в конце, поэтому, когда каталог пуст, его можно использовать безопасно rmdir()
,
foreach( new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( 'folder', FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS ),
RecursiveIteratorIterator::CHILD_FIRST ) as $value ) {
$value->isFile() ? unlink( $value ) : rmdir( $value );
}
rmdir( 'folder' );
Попробуйте простой способ:
$dir = "/home/dir";
array_map('unlink', glob($dir."/*"));
rmdir($dir);
В функции для удаления каталога:
function unlinkr($dir, $pattern = "*") {
// find all files and folders matching pattern
$files = glob($dir . "/$pattern");
//interate thorugh the files and folders
foreach($files as $file){
//if it is a directory then re-call unlinkr function to delete files inside this directory
if (is_dir($file) and !in_array($file, array('..', '.'))) {
unlinkr($file, $pattern);
//remove the directory itself
rmdir($file);
} else if(is_file($file) and ($file != __FILE__)) {
// make sure you don't delete the current script
unlink($file);
}
}
rmdir($dir);
}
//call following way:
unlinkr("/home/dir");
Вы можете использовать компонент Symfony Filesystem, чтобы избежать повторного изобретения колеса, так что вы можете сделать
use Symfony\Component\Filesystem\Filesystem;
$filesystem = new Filesystem();
if ($filesystem->exists('/home/dir')) {
$filesystem->remove('/home/dir');
}
Если вы предпочитаете управлять кодом самостоятельно, вот база кода Symfony для соответствующих методов
class MyFilesystem
{
private function toIterator($files)
{
if (!$files instanceof \Traversable) {
$files = new \ArrayObject(is_array($files) ? $files : array($files));
}
return $files;
}
public function remove($files)
{
$files = iterator_to_array($this->toIterator($files));
$files = array_reverse($files);
foreach ($files as $file) {
if (!file_exists($file) && !is_link($file)) {
continue;
}
if (is_dir($file) && !is_link($file)) {
$this->remove(new \FilesystemIterator($file));
if (true !== @rmdir($file)) {
throw new \Exception(sprintf('Failed to remove directory "%s".', $file), 0, null, $file);
}
} else {
// https://bugs.php.net/bug.php?id=52176
if ('\\' === DIRECTORY_SEPARATOR && is_dir($file)) {
if (true !== @rmdir($file)) {
throw new \Exception(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
}
} else {
if (true !== @unlink($file)) {
throw new \Exception(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
}
}
}
}
}
public function exists($files)
{
foreach ($this->toIterator($files) as $file) {
if (!file_exists($file)) {
return false;
}
}
return true;
}
}
Один из способов сделать это будет:
function unlinker($file)
{
unlink($file);
}
$files = glob('*.*');
array_walk($files,'unlinker');
rmdir($dir);
без предварительного создания массива, определенно быстрее. иногда требуется специальная обработка, почему папку нельзя удалить.
function clean_dir($dir){
$error='';
$dh=opendir($dir);
while($dh&&($file=readdir($dh))!=false){
if($file=='.'||$file=='..')continue;
$rp=$dir=='.'?$file:"$dir/$file";
if(!is_readable($rp)){$error.=PHP_EOL.$rp;continue;}
if(is_link($rp))@unlink(readlink($rp));
elseif(is_file($rp))
chmod($rp,octdec(644))!=false?@unlink($rp):$error.=PHP_EOL.$rp;
elseif(is_dir($rp)){
if(chmod($rp,octdec(755))!=false)
count(scandir($rp))==2?@rmdir($rp):clean_dir($rp);
else{$error.=PHP_EOL.$rp;}
}
}
closedir($dh);
return($error);
}
Для удаления всех файлов вы можете удалить каталог и сделать снова.. с простой строкой кода
<?php
$dir = '/home/files/';
rmdir($dir);
mkdir($dir);
?>