Хорошо, я наконец-то нашел хак для решения этой ошибки в 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 должным образом.