is_dir无法识别文件夹

问题描述:

我正在尝试制作扫描子文件夹的文件夹的函数,然后用这些文件夹的名称返回 数字数组。is_dir无法识别文件夹

这是我用于测试的代码。一旦我把它打印出来的文件夹名称,而不只是“。”和“..”为目前和以上的文件夹都会很好,我可以完成该功能。

<?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}";} 
    } 

功能只打印和“..”,而不是我希望打印的两个文件夹名称。

任何帮助表示赞赏。

+1

请编辑您的问题,以便代码可读 – jigfox 2010-06-08 14:04:17

+0

感谢您的调节,使代码可读。上次我在我的帖子中添加了代码时,它说我的权限太少,无法添加代码。试图把它包含在php中,但它仍然只是将代码作为代码进行识别。 – Rakoon 2010-06-08 14:11:01

您必须提供到file_exists的绝对路径,否则它会在当前执行路径中查找它。

while (false !== ($file = readdir($handle))) { 
    $file_path = $dir . DIRECTORY_SEPARATOR . $file; 
    if (file_exists($file_path) && is_dir($file_path)) { 
     echo "{$file}"; 
    } 
} 
+2

不需要那里的报价。 'echo $ file'工作得很好。另外,无论如何,变量插值对双引号都有效,所以你也不需要大括号。 – 2010-06-08 14:15:21

+0

变量插值对我来说是一个新词,但是,我看到代码在没有大括号的情况下执行相同。 (查找可变插值) 感谢您的快速回答,该代码现在可用。 – Rakoon 2010-06-08 14:25:01

+0

如果你没有使用大括号,也可以不用引号,这是a.t.m.只是不必要的一步。 – Wrikken 2010-06-08 14:28:07

您需要使用:

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

http://php.net/readdir

+0

感谢您的回复,看起来像上面两个答案的另一个版本。 – Rakoon 2010-06-08 14:26:51

我不认为你需要同时file_existsis_dir

你只需要is_dir功能。从手册:

is_dir如果文件名存在并且是目录,则返回TRUE,否则返回FALSE。

使用此:

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

is_dir还将检查它是否是一个相对路径或绝对路径。

+1

我不确定是谁决定让我失望,但这是有效的。我已经在我的本地apache服务器上测试过了。 – Cetra 2010-06-08 14:22:35

+0

它测试脚本当前工作目录中的目录是否存在,而不管打开了什么目录“$ handle”。它不*按预期工作。 – amphetamachine 2010-06-08 22:46:58

+0

试着打开'$ handle'到一个不是当前文件夹的目录。 – amphetamachine 2010-06-10 22:41:38

readdir的问题在于它只读取目录中指定条目的字符串。例如,如果在目录“/ path/to/files /”中有文件“foo”,那么在“/ path/to/files /”上使用readdir时,最终会得到字符串“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); 
} 
+0

这和上面的答案都适用。感谢您的快速回复。 – Rakoon 2010-06-08 14:25:45

$files = array(); 
foreach(new DirectoryIteraror('/path') as $file){ 
    if($file->isDir() /* && !$file->isDot()*/) $files[] = $file->getFilename(); 
} 

[编辑:虽然你想跳过点评论说出来)

如果你只是想启动文件夹的目录,你可以简单地做:

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

这将给你只有在数组中的文件夹名称。如果你想低于给定路径中的所有目录,尝试SPL's 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给定的路径下的所有目录。

我同意nuqqsa的解决方案,但是,我想添加一些内容。

不是指定路径,而是改变当前目录。

例如,

// open directory handle 
// .... 
chdir($dir); 
while (false !== ($file = readdir($handle))) 
if(is_dir($file)) 
    echo $file; 
// close directory handle 
+1

这最终是不好的做法;在PHP执行路径中的任何地方调用'chdir'将会改变脚本执行其余部分*整个*的当前工作目录。 I.E.如果foo.php包含执行'chdir'的bar.php,它会在bar.php包含后改变foo.php中所有内容的工作目录。 – amphetamachine 2010-06-08 22:55:12

 $directory = scandir($path); 
      foreach($directory as $a){ 
       if(is_dir($path.$a.'/') && $a != '.' && $a != '..'){ 
       echo $a.'<br/>';   
       } 
      } 

随着给出所示的路径,它显示存在于路径中的文件夹。