Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.191.189.120] |
|
Сообщ.
#1
,
|
|
|
Продолжаю мучать и поражать знатоков своими вопросами. Изучая php добрался до чтения файлов и каталогов. На первый взгляд все довольно просто. Есть несколько функций для этого (про итераторы молчу - мне до них ещё далеко). Есть scandir, glob и другие. Если указывать пути и директорию, то в указанной папке на одном уровне ищут хорошо, ну или скажем я более менее разобрался. Но вот разобраться с чтением всех уровней вложения пока не получается. С помощью GLOB_ONLYDIR удалось получить список папок на следующем уровне. Но опять же этого маловато. Вот тут нашел один пример
https://www.php.net/manual/ru/function.scandir.php#107117 function find_all_files($dir) { $root = scandir($dir); foreach($root as $value) { if($value === '.' || $value === '..') {continue;} if(is_file("$dir/$value")) {$result[]="$dir/$value";continue;} foreach(find_all_files("$dir/$value") as $value) { $result[]=$value; echo $value; echo '<br>'; /* Это я чисто для проверки результатов печатаю */ } } return $result; } find_all_files($dir); Пример прекрасно работает, но я не пойму некоторых вещей. 1. if($value === '.' || $value === '..') {continue;} Это по-видимому расшифровывается следующим образом: если $value идентично корневой папке ИЛИ идентично родительской папке, тогда продолжаем. Но родительская папка выше и её не сканирует, только корневую и те, что глубже. Что не так понимаю? 2. if(is_file("$dir/$value")) {$result[]="$dir/$value";continue;} Вообще не понимаю, кроме "если", "продолжаем" и "если єто файл". В первую очередь почему $dir и $value через слєш? $result[] по аналогии с массивами могу предположить, что это формируется массив с какой-то одинаковой частью, но какой, да и вообще, правильно ли я это понял? 3. foreach(find_all_files("$dir/$value") as $value) Это похоже на перебор, но ведь это перебор функции. Причем функции самой в себе? Ведь так называется функция (find_all_files) или это другое, просто созвучное название? тогда где оно объявлялось? И $value тут второй раз - это то же самое $value что и в первом переборе? Почему? 4. Когда и как объявляется переменная $dir? |
Сообщ.
#2
,
|
|
|
Кроме того, хоть данная функция и находит все файлы, в том числе на том уровне, где она находится, но в примере вывода $value (как у меня в комментарии) она их не показывает, хотя через var_dump они есть. И ещё есть небольшой "глюк" - некоторые файлы показывает по нескольку раз, видимо чем глубже лежат, тем больше показывает. Если быть более точным, то на сколько папок вложено, столько раз и повторяет. В строке ниже 6 вложенных папок и 6 раз повторяет этот файл при выводе.
./image/papka/portf1/portf2/portf3/portf4/baton.jpg И как я понял, выражение $result[]="$dir/$value" формирует массив, так же как и выражение $result[]=$value Это я совсем забыл про возможность формировать массив с помощью квадратных скобок. И с вызовом функции самой в себе более менее понял, что это рекурсия, но не до конца разобрался в её работе (это уже сам). Но остальные вопросы остались. В очередной раз убедился, что повторение-мать учения. Пришлось заново перечитать циклы, и оказалось все проще с вопросм №1. Видимо строка if($value === '.' || $value === '..') {continue;} расшифровывается как условие прерывания (пропуска) цикла. |
Сообщ.
#3
,
|
|
|
Разобрался со всеми вопросами ) Оказалось все гораздо проще, чем казалось на первый взгляд. Жаль, что много времени потратил. "$dir/$value" пишется через слэш потому что так задается переменная и эту запись можно заменить на равнозначную $dir.'/'.$value но уже без кавычек. Ну а $dir вообще аргумент. Да и с рекурсией в данном случае вроде разобрался.
Переделал функцию таким образом, что теперь ищет и папки и файлы с путями к ним, в том числе и в корневой папке без повторений. При необходимости выведет либо только файлы, либо только папки(дерево папок), либо файлы с путями и дерево папок(когда путь не заканчивается файлом). Получилось короче чем в примере. Может не совсем правильно, но результат есть и пока он меня устраивает. Может выложу для критики, ну или вдруг кому надо будет. Единственное, если показать ей сканировать весь диск без указания диска, а как верхний уровень"/", то покажет почему то только корень, без лазанья по папкам. А если прописать букву диска, то все в порядке. И на уровень-другой выше корневой ищет без проблем, разве что может не вложится в 30сек и прервется печать, на одном диске у меня прервался на букве "Т", а на другом отпечатал все нормально. Тоже пока не придумал как побороть. |