[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: вывод дерева папок и файлов
Жэк
Здравствуйте.

Тестирую код функции, выводящей дерево файлов и папок, взятый из (известного многим) вебинара по php:

<?php 
function
dirs($dir, $tab) {
$d = opendir($dir);
while ( $name = readdir($d) ) {
if ( $name == "." or $name == ".." ) continue;
if ( is_dir($name) ) {
echo "<b>" . $tab . "[$name]</b><br>";
#Изменённые две строки (смысл смотри в вопросе №2):
$tab2 = $tab . "-";
dirs($dir . "/$name", $tab2);
}
else {
echo "$tab$name<br>";
}
}

closedir($d);
}
dirs(".", "");



Этот вариант кода выдаёт следующее:

[admin]
-.htaccess
-admin2
-index.html
array2.php
bottom.inc.php
[comments]
-index.html
[coockies]
-coockie_def.html
-index.html
cookie.php
count.php
[css]
-common.css
data.inc.php
date.php
...


Обращаю ваше внимание на запись -admin2 - admin2 является директорией, в которой есть файлы и еще одна директория.

Вопрос: почему php-скрипт определил лежащие в корне сайта (на машине винда, стоит xampp) директории как директории, рекурсивно вызываемая функция прочитала внутри них вложенные файлы, НО вот уже вложенные внутрь директории следующих порядков она определяет НЕ как директории и выводит как простые файлы?


Это первое.

Второе.
Если запустить код, как в оригинальном примере,а именно:

<?php 
function
dirs($dir, $tab) {
$d = opendir($dir);
echo $d . "<br>";
while ( $name = readdir($d) ) {
if ( $name == "." or $name == ".." ) continue;
if ( is_dir($name) ) {
echo "<b>" . $tab . "[$name]</b><br>";
#Следующие две строки даны, "как в исходнике". В первом примере у меня они изменены
$tab = . "-";
dirs($dir . "/$name", $tab);
}
else {
echo "$tab$name<br>";
}
}

closedir($d);
}
dirs(".", "");
?>


то он выдаст в браузер дерево вида:

[admin]
-.htaccess
-admin2
-index.html
-array2.php
-bottom.inc.php
-[comments]
--index.html
--[coockies]
---coockie_def.html
---index.html
---cookie.php
---count.php
---[css]
----common.css
----data.inc.php
----date.php
----dir.php
----dirs.php
----favicon.ico
----footer.shtml
----for.php
----header.shtml
----hi.html
----hi.php
----index.html
----index.php
----index.shtml
----info.php
----lib.inc.php
----[library]
-----index.html
-----menu.inc.php


Здесь обратите внимание на то, что форматирующий вид дерева символ "-", записываемый в переменную $tab, при каждом рекурсивном вызове функции нарастает на ещё один "-", НО при возврате в предыдущий шаг рекурсии, по всей теории, как я её понимаю, должно использоваться предыдущее значение $tab, то есть в каждом шаге рекурсии создаётся своя локальная переменная $tab и при возврате в конечном итоге в корневую начальную папку последний файл должен предваряться пустым символом "", так как $tab именно пустой на первом шаге.

На практике видим, что $tab ведёт себя, как-будто если он определён как глобальная переменная - он один для всех шагов рекурсии.

В варианте, который представлен первым (смотрите самый верхний пример), при рекурсивном вызове функции параметр $tab передаётся через другую переменную $tab2. В этом случае, как видно из первого примера результата работы скрипта, всё происходит как надо.

Вопрос: почему это так и что там происходит? Почему в оригинале у Борисова И.О. всё прекрасно работает именно в его варианте - то есть и $tab ведёт себя как надо, и ВСЕ поддиректории обрабатываются?

А на моей машинке происходят такие вот две вещи, мне непонятные.

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



Спустя 2 часа, 21 минута, 7 секунд (2.12.2011 - 00:19) Placido написал(а):
Проблема в is_dir. Если в вашем варианте к имени файла/директории добавить путь is_dir($dir . '/' . $name) вместо is_dir($name), то функция работает корректно.

Насчет "глобальности" неглобальной переменной $tab во втором варианте ничего не могу сказать, мне это тоже интересно. Может, кто из экспертов подскажет?

Спустя 53 минуты, 21 секунда (2.12.2011 - 01:12) Жэк написал(а):
Дейстительно, прописать полный путь в is_dir() кажется ешением первого вопроса, отсюда хочу уточнить: какую директорию php считает текущей директорией? как сменить её? сменяет ли её opendir()?


вопрос про "глобальность" неглобальной $tab открыт.

Спустя 10 минут, 35 секунд (2.12.2011 - 01:23) Игорь_Vasinsky написал(а):
ответ в вопросе wink.gif
Цитата
: какую директорию php считает текущей директорией?

Спустя 27 минут, 8 секунд (2.12.2011 - 01:50) Жэк написал(а):
Цитата (Игорь_Vasinsky @ 1.12.2011 - 22:23)
ответ в вопросе wink.gif
Цитата
: какую директорию php считает текущей директорией?

потуги "мудрых"

Спустя 8 часов, 58 минут, 18 секунд (2.12.2011 - 10:48) Placido написал(а):
Разобрался.
Дело в том, что readddir() читает все элементы папки так, как они хранятся в файловой системе, а не по типам элементов. Т.е. читается все подряд, независимо от того, файл это или папка. А присваивая $tab .= "-" после того, как мы находим директорию (is_dir), но перед тем как запустить рекурсию, мы с каждой новой директорией добавляем в локальную переменную $tab еще один "-". Вместо этого нужно передавать новое значение $tab в рекурсивную функцию (это мы и делаем в случае с использованием $tab2), а само локальное значение $tab должно оставаться неизменным, чтобы оно могло быть использоваться на этом же уровне с другими элементами текущей папки. Можно изменить код так:
if (is_dir($dir. '/' . $name)) {
echo "<b>" . $tab . "[$name]</b><br>";
//$tab .= "-";
dirs($dir . '/' . $name, $tab . "-");
}

В этом случае все работает.

Спустя 1 час, 11 минут, 10 секунд (2.12.2011 - 11:59) Жэк написал(а):
Блин. Точно так и есть))
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.