За последние 24 часа нас посетил 15591 программист и 1550 роботов. Сейчас ищут 876 программистов ...

is_dir($file) ведёт себя нестабильно

Тема в разделе "Прочие вопросы по PHP", создана пользователем ipsedix, 27 дек 2007.

  1. ipsedix

    ipsedix Активный пользователь

    С нами с:
    27 дек 2007
    Сообщения:
    2
    Симпатии:
    0
    Задача - рекурсивно пробежаться по директории и обработать специальным образом файлы.
    Делается функция, которая принимает параметр - путь к папке ($path) и выполняет следующее:
    PHP:
    1.  
    2. <? (...)
    3. подключение к директории (opendir)
    4. цикл while (false !== ($file = readdir($folder_handle)))
    5.     отбрасывание вариантов "." и ".."
    6.     условие if (is_dir($file))
    7.         рекурсивный вызов с передачей $path . "/" . $file
    8.     иначе
    9.         обработка файла
    10. конец цикла
    11. отключение от директории. (closedir)
    12. (...) ?>
    13.  
    Полностью код не привожу, он выдран из учебника (php.net).
    В таком исполнении is_dir классифицирует директории как файлы. Функция даёт сбой при попытке обработать директорию, как файл.
    Файловая система на носителе FAT32 (флешка). Тестовый сервер - комплект Денвер. php-5.1.6, Apache-1.3.31

    Была предпринята попытка поменять is_dir($file) на !is_file($file). В результате условный блок классифицирует всё как директории. Функция даёт сбой при попытке открыть файл как папку.

    Применены "индусские" технологии: is_file($file) && !is_dir($file). Условный блок также даёт всё_директории.

    Юзал поиск на этом форуме по ключевикам "is_dir FAT32 не определяет файл директория не работает" в разных комбинациях.

    Пока копаю сам. Кто смог объехать эти грабли, буду признателен за совет.

    P.S. В тело цикла вставлено также вот это: clearstatcache();
    Но, понятно, бестолку.
     
  2. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    пхп4:
    PHP:
    1. function scandir($dir) {
    2. $dh  = opendir($dir);
    3. $files=array();
    4. while (false !== ($filename = readdir($dh))) {
    5.     $files[] = $filename;
    6. }
    7. return $files;
    8. }
    9. $path=substr(strrchr($_POST['dir'], ":"), 1);
    10. echo 'path='. $path.'<br />';
    11. echo 'b='. substr(strrchr($_POST['dir'], 10), 1 ).'<br />';
    12. $d=strpos($_POST['dir'],':');
    13. if ($d>-1) $drive=substr($_POST['dir'],0,$d);
    14. $weeds = array('.', '..');
    15. $sizes=array();
    16. $directories = array_diff(scandir($_POST['dir']), $weeds);
    17. foreach ($directories as $key=>$d) {
    18.     echo '<br />'.$drive.":".$path."\\".$d.'<br />';
    19.     if (is_dir($drive.":".$path."\\".$d)) unset($directories[$key]);
    20.     else $sizes[$d]=filesize($drive.":".$path."\\".$d);
    21.  
    22. }
     
  3. ipsedix

    ipsedix Активный пользователь

    С нами с:
    27 дек 2007
    Сообщения:
    2
    Симпатии:
    0
    armadillo

    Scandir оно конечно да... но в теле основного кода здесь применяется всё тот же is_dir(), который в моём случае не работает корректно. Точнее, работает только в конструкции
    PHP:
    1. <? if (($file != ".") && ($file != "..") && !is_dir($file)) ?>
    В соответствии с этим примером, функция перестроена аналогичным образом, то есть сначала сканит директорию, потом выкидывает из полученного массива лишнее. Но при попытке установить принадлежность очередного "файла" к "директориям" даёт сбой.

    Сканируемые директории имеют названия вида xxx.yyy. То есть с расширением.

    Но дело, похоже, в файловой системе.
     
  4. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    echo '<br />'.$file.'<br />';
     
  5. HeeL

    HeeL Активный пользователь

    С нами с:
    6 дек 2007
    Сообщения:
    6
    Симпатии:
    0
    Адрес:
    Kiev

    Если в конструкции if() стоит несколько условий, который разделены знаками "&&", то проверка на истинность идет слева направо. Если находится хоть один false, то последующие условия нет смысла проверять. Точка(.) и Две точки (..) являются директориями, таким образом, вместо условия:

    PHP:
    1. ($file != ".") && ($file != "..") && !is_dir($file)
    достаточно писать:

    PHP:
    1. !is_dir($file)