PHP / Windows - Opendir () не может открыть подкаталоги в символьных связанных каталогах - PullRequest
0 голосов
/ 25 мая 2010

Кто-нибудь знает решение этой проблемы? Я не могу открыть подкаталог в каталоге symboliclink'd. Я подтвердил, что пути правильные (даже скопировал и вставил путь в проводник, который хорошо его проанализировал). Это странная, раздражающая ошибка: |.

Пример:

C: \ folder \ symbolic_link \ dir1 \ dir2 - открытие dir2 завершается неудачно.

C: \ folder \ symbolic_link \ dir1 - работает

C: \ folder \ real_directory \ dir1 \ dir2 - работает

C: \ folder \ real_directory \ dir1 - работает

1 Ответ

0 голосов
/ 03 июня 2010

Хорошо, я наконец-то нашел хак для решения этой ошибки в php-обработке символических ссылок в windows. Ошибка возникает при рекурсивной итерации файлов / каталогов с использованием opendir(). Если в текущем каталоге существует символическая ссылка на каталог, opendir() не сможет прочитать каталоги в символьной ссылке каталога. Это вызвано чем-то напуганным в statcache php, и его можно решить, вызвав clearstatcache() перед вызовом opendir() по символьной ссылке каталога (также, дескриптор файла родительского каталога должен быть закрыт).

Вот пример исправления:

<?php

class Filesystem
{
    public static function files($path, $stats = FALSE)
    {
        clearstatcache();

        $ret = array();
        $handle = opendir($path);
        $files = array();

        // Store files in directory, subdirectories can't be read until current handle is closed & statcache cleared.
        while (FALSE !== ($file = readdir($handle)))
        {
            if ($file != '.' && $file != '..')
            {
                $files[] = $file;
            }
        }

        // Handle _must_ be closed before statcache is cleared, cache from open handles won't be cleared!
        closedir($handle);

        foreach ($files as $file)
        {
        clearstatcache($path);

            if (is_dir($path . '/' . $file))
            {
                $dir_files = self::files($path . '/' . $file);

                foreach ($dir_files as $dir_file)
                {
                    $ret[] = $file . '/' . $dir_file;
                }
            }
            else if (is_file($path . '/' . $file))
            {
                $ret[] = $file;
            }
        }

        return $ret;
    }
}

var_dump(filessystem::files('c:\\some_path'));

Редактировать: Кажется, что clearstatcache($path) должен быть вызван до любых функций обработки файлов в директории symlink'd. Php не кэширует dim-файлы symlink'd должным образом.

...