На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: Serafim, fatalist
  
    > Чтение каталогов и файлов с использованием scandir из Мануала, Функция прикольная, но как работет не пойму, а к ней ещё пару примеров
      Продолжаю мучать и поражать знатоков своими вопросами. Изучая php добрался до чтения файлов и каталогов. На первый взгляд все довольно просто. Есть несколько функций для этого (про итераторы молчу - мне до них ещё далеко). Есть scandir, glob и другие. Если указывать пути и директорию, то в указанной папке на одном уровне ищут хорошо, ну или скажем я более менее разобрался. Но вот разобраться с чтением всех уровней вложения пока не получается. С помощью GLOB_ONLYDIR удалось получить список папок на следующем уровне. Но опять же этого маловато. Вот тут нашел один пример
      https://www.php.net/manual/ru/function.scandir.php#107117
      ExpandedWrap disabled
          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?
        Кроме того, хоть данная функция и находит все файлы, в том числе на том уровне, где она находится, но в примере вывода $value (как у меня в комментарии) она их не показывает, хотя через var_dump они есть. И ещё есть небольшой "глюк" - некоторые файлы показывает по нескольку раз, видимо чем глубже лежат, тем больше показывает. Если быть более точным, то на сколько папок вложено, столько раз и повторяет. В строке ниже 6 вложенных папок и 6 раз повторяет этот файл при выводе.
        ExpandedWrap disabled
          ./image/papka/portf1/portf2/portf3/portf4/baton.jpg
        Убрать повторяющиеся с помощью array_unique у меня пока не получилось.
        И как я понял, выражение $result[]="$dir/$value" формирует массив, так же как и выражение $result[]=$value Это я совсем забыл про возможность формировать массив с помощью квадратных скобок. И с вызовом функции самой в себе более менее понял, что это рекурсия, но не до конца разобрался в её работе (это уже сам). Но остальные вопросы остались.

        В очередной раз убедился, что повторение-мать учения. Пришлось заново перечитать циклы, и оказалось все проще с вопросм №1. Видимо строка if($value === '.' || $value === '..') {continue;} расшифровывается как условие прерывания (пропуска) цикла.
        Сообщение отредактировано: D-G -
          Разобрался со всеми вопросами ) Оказалось все гораздо проще, чем казалось на первый взгляд. Жаль, что много времени потратил. "$dir/$value" пишется через слэш потому что так задается переменная и эту запись можно заменить на равнозначную $dir.'/'.$value но уже без кавычек. Ну а $dir вообще аргумент. Да и с рекурсией в данном случае вроде разобрался.
          Переделал функцию таким образом, что теперь ищет и папки и файлы с путями к ним, в том числе и в корневой папке без повторений. При необходимости выведет либо только файлы, либо только папки(дерево папок), либо файлы с путями и дерево папок(когда путь не заканчивается файлом). Получилось короче чем в примере. Может не совсем правильно, но результат есть и пока он меня устраивает. Может выложу для критики, ну или вдруг кому надо будет.
          Единственное, если показать ей сканировать весь диск без указания диска, а как верхний уровень"/", то покажет почему то только корень, без лазанья по папкам. А если прописать букву диска, то все в порядке. И на уровень-другой выше корневой ищет без проблем, разве что может не вложится в 30сек и прервется печать, на одном диске у меня прервался на букве "Т", а на другом отпечатал все нормально. Тоже пока не придумал как побороть.
          Сообщение отредактировано: D-G -
          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script Execution time: 0,0660 ]   [ 14 queries used ]   [ Generated: 12.11.19, 14:25 GMT ]