is_dir не распознает папки - PullRequest
4 голосов
/ 08 июня 2010

Я пытаюсь создать функцию, которая сканирует папку на наличие подпапок, а затем возвращает числовой массив с именами этих папок.

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

<?php
function super_l_getthemes($dir="themes")
{

if ($handle = opendir($dir)) {
    echo "Handle: {$handle}\n";
    echo "Files:\n";


    while (false !== ($file = readdir($handle))) {
       echo "{$file}<br>";
    }

    closedir($handle);
}
?>

Приведенный выше код работает нормально, и распечатывает все содержимое папки: файлы, подпапкии "."и ".."

, но если я заменю:

  while (false !== ($file = readdir($handle))) {
       echo "{$file}<br>";
    }

на:

while (false !== ($file = readdir($handle))) {
        if(file_exists($file) && is_dir($file)){echo "{$file}";}
    }

Функция только печатает "."и "..", а не два имени папки, которые я бы хотел напечатать.

Любая помощь приветствуется.

Ответы [ 8 ]

6 голосов
/ 08 июня 2010

Вы должны указать абсолютный путь к file_exists, иначе он будет искать его в текущем пути выполнения.

while (false !== ($file = readdir($handle))) {
    $file_path = $dir . DIRECTORY_SEPARATOR . $file;
    if (file_exists($file_path) && is_dir($file_path)) {
        echo "{$file}";
    }
}
3 голосов
/ 08 июня 2010

Проблема с readdir заключается в том, что он читает только строки именованных записей внутри каталога.

Например, если у вас есть файл "foo" внутри каталога "/ path / to /files / ", при использовании readdir в" / path / to / files / ", вы в конечном итоге получите строку" foo ".

Обычно это не будет проблемой, если это будеттот же каталог, что и текущий рабочий каталог скрипта, но, так как вы читаете из произвольного директора, когда вы пытаетесь проверить запись (файл, каталог, что угодно), вы вызываете is_dir в пустой строке "foo".

Я бы попытался добавить префикс к имени, которое вы извлекаете, используя readdir с путем к файлу.


if ($handle = opendir($dir)) {
    echo "Handle: {$handle}\n";
    echo "Files:\n";

    while ($file = readdir($handle)) {
        /*** make $file into an absolute path ***/
        $absolute_path = $dir . '/' . $file;

        /*** NOW try stat'ing it ***/
        if (is_dir($absolute_path)) {
            /* it's a directory; do stuff */
        }
    }

    closedir($handle);
}
1 голос
/ 08 июня 2010

Если вам нужны только каталоги начальной папки, вы можете просто сделать:

glob('/some/path/to/search/in/*', GLOB_ONLYDIR);

, который дал бы вам только те имена в массиве. Если вы хотите, чтобы все каталоги были ниже указанного пути, попробуйте SPL RecursiveDirectoryIterator

$fileSystemIterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator('/some/path/to/look/in'),
    RecursiveIteratorIterator::SELF_FIRST);

Итераторы могут использоваться с foreach:

$directories = array();
foreach($fileSystemIterator as $path => $fileSystemObject) {
    if($fileSystemObject->isDir()) {
        $directories[] = $path;
    }
}

После этого у вас будет массив $directories со всеми каталогами по указанному пути.

1 голос
/ 08 июня 2010

Вам необходимо использовать:

while (false !== ($file = readdir($handle))) {
    if(file_exists($dir.'/'.$file) && is_dir($dir.'/'.$file)){echo "{$file}";}
}

См. http://php.net/readdir

0 голосов
/ 21 апреля 2013
        $directory = scandir($path);
            foreach($directory as $a){
                if(is_dir($path.$a.'/') && $a != '.' && $a != '..'){
                echo $a.'<br/>';        
                }
            }

При указанном пути, как показано, отображаются папки, присутствующие в пути.

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

Я согласен с решением nuqqsa, однако я хотел бы добавить что-то к нему.

Вместо указания пути вы можете изменить текущий каталог.

Например,

// open directory handle
// ....
chdir($dir);
while (false !== ($file = readdir($handle)))
 if(is_dir($file))
  echo $file;
// close directory handle
0 голосов
/ 08 июня 2010
$files = array();
foreach(new DirectoryIteraror('/path') as $file){
    if($file->isDir() /* && !$file->isDot()*/) $files[] = $file->getFilename();
}

[править: хотя вы хотели пропустить точку, прокомментировали ее)

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

Не думаю, что вам нужны и file_exists, и is_dir,

Вам просто нужна функция is_dir. Из руководства:

is_dir Возвращает TRUE, если имя файла существует и является каталогом, иначе FALSE.

Используйте это:

while (false !== ($file = readdir($handle))) {
        if(is_dir($file)){echo "{$file}";}
    }

is_dir также проверит, является ли это относительным или абсолютным путем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...