Использование scandir() для поиска папок в каталоге (PHP)

Я использую этот кусок кода:

$target = 'extracted/' . $name[0];  
$scan = scandir($target);

Для сканирования каталога папки, которая используется для загрузки zip. Я хочу иметь возможность найти все папки в моей папке $target, чтобы я мог удалить их и их содержимое, оставив только файлы в каталоге $target.

После того, как я вернул содержимое папки, я не знаю, как различать папки и файлы, чтобы иметь возможность удалять папки.

Кроме того, мне сказали, что функция rmdir() не может удалять папки, в которых есть содержимое, есть ли способ обойти это?

Спасибо, Бен.


person Ben McRae    schedule 03.03.2009    source источник


Ответы (9)


Чтобы определить, есть ли у вас папка или файл, используйте функции is_dir() и is_file().

Например:

$path = 'extracted/' . $name[0];
$results = scandir($path);

foreach ($results as $result) {
    if ($result === '.' or $result === '..') continue;

    if (is_dir($path . '/' . $result)) {
        //code to use if directory
    }
}
person travis-146    schedule 03.03.2009
comment
Это гениально, работает отлично! К сожалению, я не понимаю, что делает эта часть 'if ($result === '.' или $result === '..') continue;', не могли бы вы объяснить, пожалуйста. Спасибо еще раз. - person Ben McRae; 04.03.2009
comment
@Ben McRae: Это потому, что scandir возвращает результаты. и .. как часть массива, и в большинстве случаев вы хотите игнорировать эти результаты, поэтому я включил это как часть foreach - person travis-146; 05.03.2009
comment
Просто добавлю немного дополнительной информации: . представляет текущий каталог, а .. представляет родительский каталог папки. - person shock_gone_wild; 08.10.2015

Лучше использовать DirectoryIterator.

$path = 'extracted'; // '.' for current
foreach (new DirectoryIterator($path) as $file) {
    if ($file->isDot()) continue;

    if ($file->isDir()) {
        print $file->getFilename() . '<br />';
    }
}
person Dominic    schedule 11.03.2011

Во-первых, rmdir() не может удалить папку с содержимым. Если безопасный режим отключен, вы можете использовать следующее.

exec("rm -rf folder/"); 

Также обратите внимание на is_dir()/is_file() или, что еще лучше, на PHP SPL.

person Hawk Kroeger    schedule 03.03.2009

$directories = scandir('images');
foreach($directories as $directory){
    if($directory=='.' or $directory=='..' ){
        echo 'dot';
    }else{
            if(is_dir($directory)){
                  echo $directory .'<br />';
            }
    }
} 

более простая и, возможно, более быстрая версия

person alex    schedule 14.07.2010
comment
вы не фильтруете, является ли результат в else каталогом или нет, позвольте мне отредактировать и обновить его - person Steel Brain; 29.12.2013

scandir будет сканировать весь каталог, вы можете отфильтровать вручную.

но если вы ленивы, как я, то используйте glob

$scan = glob($target."/*",GLOB_ONLYDIR);

и он выведет массив всех ваших каталогов вашей цели.

person ジェンネ    schedule 07.10.2015
comment
Это действительно сработало. Мне понравилось. и тоже использовал. Спасибо - person Saiful Islam; 11.12.2017

Чтобы получить все файлы во всех подпапках

function myfunction($dir){

foreach ($dir as $dirname => $file) {

if(is_dir($file) &&  $file != '.' &&  $file != '..' ) { 

     // echo $file;
      $newDir = scandir($file);
      myfunction($newDir);

    }elseif($file !='.' && $file != '..'){

        echo "<br>File name is ---";
        echo  $file;
    }

} // end foreach


}  //function ends 

$dirpass = scandir($mypath3); // set directory
echo myfunction($dirpass); //     pass directory

Мы получим результат, как показано ниже (пожалуйста, игнорируйте имена файлов)

File name is ----->index.PHP
File name is -----> 100000045   Invoices   Sales   Magento Admin.png
File name is -----> 100000142   Orders   Sales   Magento Admin(1).png
File name is -----> 100000142   Orders   Sales   Magento Admin.png
File name is ----->hrc-siberian-tiger-2-jpg_21253111.jpg
File name is ----->images (3rd copy).jpeg
File name is ----->images (4th copy).jpeg
File name is ----->images (5th copy).jpeg
File name is ----->images (another copy).jpeg
File name is ----->images (copy).jpeg
File name is ----->images.jpeg
File name is ----->JPEG_example_JPG_RIP_100.jpg
File name is ----->preload
File name is ----->Stonehenge (3rd copy).jpg
File name is ----->Stonehenge (4th copy).jpg
File name is ----->Stonehenge (5th copy).jpg
File name is ----->Stonehenge (another copy).jpg
File name is ----->Stonehenge (copy).jpg
File name is ----->Stonehenge.jpg
person inrsaurabh    schedule 20.06.2017

Вы также хотели удалить элементы, если они находились внутри этого каталога. rmdir не позволяет удалять каталоги, содержащие файлы. Но есть простое решение.

array_map('unlink', glob($target.'/*/*'));
array_map('rmdir',glob($target."/*",GLOB_ONLYDIR));

Во-первых, он разъединит все файлы во всех подкаталогах.
Во-вторых, удалит все каталоги, так как в них нет файлов.

Если у вас есть под-подкаталоги, то вы должны добавить еще 2 строки, например:

array_map('unlink', glob($target.'/*/*/*')); //remove sub-sub-files
array_map('rmdir',glob($target."/*/*",GLOB_ONLYDIR)); //remove sub-sub-directories

array_map('unlink', glob($target.'/*/*')); //remove sub-files
array_map('rmdir',glob($target."/*",GLOB_ONLYDIR)); //remove sub-directories
person ジェンネ    schedule 08.10.2015

Быстрый и грязный способ:

$folders = glob("<path>/*", GLOB_ONLYDIR);

Более универсальное и объектно-ориентированное решение, вдохновленное более ранними ответами с использованием DirectoryIterator, но немного более лаконичное и универсальное:

    $path = '<path>';
    $folders = [];

    foreach (new \DirectoryIterator($path) as $file)
    {
        if (!$file->isDot() && $file->isDir())
        {
            $folders[] = $file;
        }
    }
person Andreas Bergström    schedule 27.01.2017

вот одна функция, которую я использовал в основном для разбора архивов и каталогов

function scan_full_dir($dir,$child=false){
    $dir_content_list = scandir($dir);
    foreach($dir_content_list as $value) 
    { 
        if($value === '.' || $value === '..') {continue;} 
        // check if we have file 
         if(is_file($dir.'/'.$value)) {
            echo '<br> File Name --> '.$value;
            continue; 
         }
        // check if we have directory
        if (is_dir($dir.'/'.$value)) {
            if(!$child){ 
                echo '<br> parent --> '.$value;
            }else{
                echo '<br> child of '.$child.' --> '.$value;    
            }
            scan_full_dir($dir.'/'.$value,$value);
        }       
    }   
}

выходной образец

parent --> fonts
File Name --> standard
parent --> steps
child of steps --> pcb
File Name --> .attrlist.sum
File Name --> .profile.sum
File Name --> .stephdr.sum
File Name --> attrlist
child of pcb --> netlists
child of netlists --> cadnet
File Name --> .netlist.sum
File Name --> netlist
File Name --> profile
File Name --> stephdr

// для сканирования каталога

scan_full_dir('path/of/myfolder');

// для сканирования архива, не открывая его, поддерживаемые форматы: файлы gz, zip, tar и bz.

scan_full_dir('phar://uploads/youarchive.zip);
person user889030    schedule 06.03.2019