Работа с каталогами PHP
function printTree(int $level = 1) : void { $dir = opendir('.'); if (!$dir) return; while (($file = readdir($dir)) !== false) { if ($file == '.' || $file == '..') continue; if (!is_dir($file)) continue; for ($i = 0; $i < $level; $i++) echo ' '; echo $file . PHP_EOL; if (!chdir($file)) continue; printTree($level + 1); chdir('..'); flush(); } closedir($dir); } // Структура каталогов: main_catalog sub_catalog file1.php file2.php next_sub_folder В $dir, при запуске функции - дескриптор main_catalog Не понятно, что происходит, когда функция запрыгнет в sub_catalog и разшарит все файлы там. Директория будет закрыта, дальше управление перейдет во внешний вызов сюда: chdir('..') - выход наверх в main_catalog. Во внешнем вызове, на следующей итерции while в $file будет содержатся next_sub_folder. Как связан chdir('..') и то что содержится в $file? Ну то есть в первом вызове readdir($dir) возвращает все содержимое main_catalog, потом, после выпрыгивания из sub_catalog, на следующей итерации while readdir($dir) возвращает следующую директорию. Не могу точно сформулировать, chdir('..') влияет на эту переменную $dir? |
function printTree(int $level = 1) : void { // открываем дескриптор текущей директории $dir = opendir('.'); // завершаем работу функции, если не удалось открыть дескриптор if (!$dir) return; // перебираем элементы директории по её дескриптору while (($file = readdir($dir)) !== false) { // если это ссылка на текущую директорию или родительскую - игнорируем этот элемент if ($file == '.' || $file == '..') continue; // если это не директория - игнорируем этот элемент if (!is_dir($file)) continue; // выводим "отступ" от левого края for ($i = 0; $i < $level; $i++) echo ' '; // выводим название директории echo $file . PHP_EOL; // пытаемся изменить текущую директорию на дочернюю директорию $file // если не удалось - пропускаем директорию $file if (!chdir($file)) continue; // рекурсивно вызываем эту же функцию, чтобы она // отобразила "дерево" каталогов, но уже для дочерней директории $file printTree($level + 1); // изменяем текущую директорию на изначальную chdir('..'); // непонятно зачем, но пытаемся сбросить буфер вывода flush(); } // закрываем дескриптор closedir($dir); } |
Nexus,
это все так. Непонятно просто как под капотом работает. Когда будет выход из дочерней директории цикл во внешнем вызове после смены директории на изначальную запоминает на каком месте остановился? Видимо запоминает, без chdir('..') не работает. |
Цитата:
Дескриптор родительского каталога не закрывается до тех пор, пока все директории изначального каталога не будут перечислены. |
Цитата:
|
Цитата:
opendir - открывает дескриптор указанной первым аргументом директории. Без chdir не работает, поскольку функция пытается получить исключительно дескриптор текущей директории (working directory). Эту функцию можно переписать и без использования chdir, передавая функции printTree путь до каталога, дерево которого нужно вывести. function printTree(string $path): void { $handle = opendir($path); if (!$handle) { return; } // and so on } |
Nexus,
понятно, спасибо. |
Часовой пояс GMT +3, время: 00:10. |