Рекрусивное удаление пустых каталогов (PHP)

Честно говоря я не пользуюсь итераторами из-за незнания.
Понимаю, что можно зайти на сайт и почитать, но это время...
Я уже далеко не студент и сложно следить за нововведениями...
 
я объясню причину своего интереса: в последнее время стал обращать внимание, что мало кто пользуется spl, итераторами и т.п. встроенным и чертовски удобным и малословным функционалом.. что это?.. не желание/способность воспринимать новое?..
частично - инертность, частично - наличие старых мануалов в сети (многие "гуглят" по-русски и от официальной документации шарахаются - "это же на англицком!"), частично - страх перед "многабукаф" (итератор это ведь что-то замудрёное.. куда проще opendir)

Достаточно внешний вид сравнить.
Код:
$idir = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, FilesystemIterator::SKIP_DOTS ), 
RecursiveIteratorIterator::CHILD_FIRST );
и
Код:
$dh = opendir ($dir);
 
Ага, понял... То есть, в моем случае можно упростить:
PHP:
function rmdir_empty($root)
{
    $root = realpath($root);
    if ($root AND is_dir($root))
    {
        foreach (scandir($root) AS $file)
        {
            if ($file == '.' OR $file == '..')
                continue;

            if (is_dir($root . DIRECTORY_SEPARATOR . $file))
                rmdir_empty($root . DIRECTORY_SEPARATOR . $file, true);
        }
    }
}

rmdir_empty('upload');
Все, всем спасибо )))
нет конечно, там параметр нужен внутренне для удаления подкаталогов. просто вызывайте rmdir_empty('directory_path');
 
Для просмотра ссылки Войди или Зарегистрируйся, можно поинтересоваться, чем мой вариант не устроил?..

я объясню причину своего интереса: в последнее время стал обращать внимание, что мало кто пользуется spl, итераторами и т.п. встроенным и чертовски удобным и малословным функционалом.. что это?.. не желание/способность воспринимать новое?.. необходимость поддерживать дважды устаревшую версию 5.2 (уже 5.3 заморожена, только багфиксы).. всё же это наитивно, написано на сях, уж точно будет работать быстрее прогона через интерпретатор (т.б. рекурсивно)..

растолкуйте мне, серому, пожалуйста.. ))
Да без проблем только $f = glob( $idir->key() . '/*.*' ); лишнее. А также протестируйте производительность ради интереса на каталоге с сложной структурой. Я вообще использовал бы readir - самый быстрый вариант.

По интераторам уже производили тестирование, не помню где это было, но результаты были удручающими.
 
вы хоть понимаете, что вы одну единственную директорию просматриваете, а я рекурсивно все вложенные?.. т.е. я решение предлагаю, а вы троллите..
Достаточно внешний вид сравнить.
Код:
$idir = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, FilesystemIterator::SKIP_DOTS ),
RecursiveIteratorIterator::CHILD_FIRST );
и
Код:
$dh = opendir ($dir);
[/sp
частично - инертность, частично - наличие старых мануалов в сети (многие "гуглят" по-русски и от официальной документации шарахаются - "это же на англицком!"), частично - страх перед "многабукаф" (итератор это ведь что-то замудрёное.. куда проще opendir)

Достаточно внешний вид сравнить.
Код:
$idir = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, FilesystemIterator::SKIP_DOTS ),
RecursiveIteratorIterator::CHILD_FIRST );
и
Код:
$dh = opendir ($dir);
 
вы хоть понимаете, что вы одну единственную директорию просматриваете, а я рекурсивно все вложенные?..
Я об это не подумал... Хотя задача заключалась именно в просмотре одной категории...
т.е. я решение предлагаю, а вы троллите..
Да никто не троллит, просто твое решение чуть сложнее для понимания. Например я смогу оценить только после прочтения манов...
 
По интераторам уже производили тестирование, не помню где это было, но результаты были удручающими.
Понимаю, что пруфов не будет.. Насколько удручающие? В 2 раза? В 10 раз? Что с чем сравнивали?
Рекурсивный glob вываливается по таймауту или по мемори лимиту, там где рекурсивный итератор отрабатывает за ~1,5 секунды и находит ~ 150к элементов. Рекурсивный opendir+readdir показывает примерно такие же результаты (~1,5-1,7 с), код при этом чуть запутанней (если вникнуть).. Особенно, проявляется, если нужны какие-либо действия с результатом. Итератор можно обойти как массив, а если этот массив собирать рекурсивно - расход памяти будет значительно больше.. Придётся непосредственно обработку встраивать в рекурсивную функцию.

вы хоть понимаете, что вы одну единственную директорию просматриваете, а я рекурсивно все вложенные?.. т.е. я решение предлагаю, а вы троллите..
BDSG, не стоит принимать так близко к сердцу.. Задал вопрос - получил ответ. Могу перевести: изначально отпугивает размер кода и "неочевидность".. и не важно, что FilesystemIterator::SKIP_DOTS и RecursiveIteratorIterator::CHILD_FIRST - это всего лишь числа, а технически работать с итератором не сложнее, чем с массивом.

p.s. 4BDSG Во избежание... Сам понимаю и использую итераторы, доки читаю и перед тем, Для просмотра ссылки Войди или Зарегистрируйся проверяю, если не уверен..
 
вы хоть понимаете, что вы одну единственную директорию просматриваете, а я рекурсивно все вложенные?.. т.е. я решение предлагаю, а вы троллите..
Учите программирование товарищ и не говорите глупостей. А троллите вы в данном случае, я вам лишь сказал что операция glob и if лишние.
 
Последнее редактирование:
Понимаю, что пруфов не будет..
Сорри, я не могу найти.

Вот тест:
PHP:
$dir = 'C:\\Windows';

$start_time = microtime(true);
get_all_dirs($dir);
echo (microtime(true) - $start_time);
exit;
// 43.167906999588

PHP:
$dir = 'C:\\Windows';

$start_time = microtime(true);
get_all_dirs_i($dir);
echo (microtime(true) - $start_time);
exit;
// 67.356878995895

PHP:
function get_all_dirs($path)
{
   $dh = opendir($path);
   while ($file = readdir($dh))
   {
     if ($file != '.' AND $file != '..' AND is_dir($path . DIRECTORY_SEPARATOR . $file))
     {
       get_all_dirs($path . DIRECTORY_SEPARATOR . $file);
     }
   }
}

function get_all_dirs_i($path)
{
   $dirs = new RecursiveIteratorIterator(
     new RecursiveDirectoryIterator(
       $path,
       FilesystemIterator::SKIP_DOTS
     ),
     RecursiveIteratorIterator::CHILD_FIRST
   );

   foreach ($dirs AS $dir)
   {
     if ($dir->isDir())
       null;
   }
}
 
Последнее редактирование:
Для просмотра ссылки Войди или Зарегистрируйся, не правильно вы тест построили.. не равнозначно.. в вашем случае он должен выглядеть так:
PHP:
$iterations = 100;
$target_dir = 'some/path';

function get_all_dirs_i( $path ){

    $f = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST );
    if( $f->isDir() );
}

function get_all_dirs($path){
    $dh = opendir($path);
    while ($file = readdir($dh)){
        if ($file != '.' AND $file != '..' AND is_dir($path . DIRECTORY_SEPARATOR . $file)){

            get_all_dirs($path . DIRECTORY_SEPARATOR . $file);
        }
    }
}

$microtime_on_start = microtime( true );
$memory_on_start = memory_get_usage();


for( $i=0; $i<=$iterations; ++$i ){

    get_all_dirs_i( $target_dir );
}

echo number_format( ( microtime( true ) - $microtime_on_start ), 10, '.', "'" ) . ', ' . ( memory_get_usage() - $memory_on_start ) . "\n";


$microtime_on_start = microtime( true );
$memory_on_start = memory_get_usage();

for( $i=0; $i<=$iterations; ++$i ){

    get_all_dirs( $target_dir );
}

echo number_format( ( microtime( true ) - $microtime_on_start ), 10, '.', "'" ) . ', ' . ( memory_get_usage() - $memory_on_start ) . "\n";

тут уже совсем другой коленкор..

(354 файлов, пол-сотни папок)
итератор - 0.0039999485, 240
рекурсия - 4.0612330437, 520

зы.. на папке c:\windows нельзя проверять - ко многим папкам/директориям нет доступа.. бросаются исключения.. которые тяжелы сами по себе..
 
Последнее редактирование:
Назад
Сверху