使用PHP获取目录中所有文件的名称

102

使用这段代码我总是得到文件名称中的 '1' ,不知道什么原因:

if (is_dir($log_directory))
{
    if ($handle = opendir($log_directory))
    {
        while($file = readdir($handle) !== FALSE)
        {
            $results_array[] = $file;
        }
        closedir($handle);
    }
}
当我用$ results_array中的每个元素进行回显时,我得到一堆“1”,而不是文件的名称。我如何获取文件名?

1
有几个选项可以使用glob - allnightgrocery
1
海报遇到的问题是赋值运算符优先级非常低,因此'!=='运算符首先被评估,然后该操作的二进制结果被分配给$file。唯一需要修复的是使用"($file = readdir($handle)) !== FALSE"。 - Omn
这个可以用:https://halgatewood.com/free-php-list-files-in-a-directory-script - Gabriel
从69票到70票。我感觉像汉克·穆迪的反面。 - Bruno Francisco
16个回答

196

不要费心使用open/readdir,可以使用glob代替:

foreach(glob($log_directory.'/*.*') as $file) {
    ...
}

27
因为问题要求文件,所以你可能希望在该全局函数 glob 周围加上 array_filter(..., 'is_file') - salathe
28
并不是所有的文件名都是 *.* 的形式:可以直接使用 * 代替。 - jameshfisher
我们如何获取指定扩展名列表中的所有文件?例如,如果我们想要所有的 .php 和 .js 文件? - Nis
3
是的,这个答案不够健壮。文件不需要扩展名,目录可以命名为“something.something”。最好使用array_filterglob($log_directory.'/*') - Andrew
我点赞了这个回答,因为我只需要简单的答案,而且对于我的用例来说,所有相关文件都是 *.*。一个更强大的表达式会使这个答案变得更好。 - TecBrat
显示剩余6条评论

60

SPL 风格:

foreach (new DirectoryIterator(__DIR__) as $file) {
  if ($file->isFile()) {
      print $file->getFilename() . "\n";
  }
}

查看DirectoryIteratorSplFileInfo类,以获取您可以使用的可用方法列表。


获取文件名而非整个路径的好方法,感谢! - Chris
1
是的。对于完整路径,您可以使用 getPathname:http://php.net/manual/en/splfileinfo.getpathname.php - Ilija

24

由于被接受的答案存在两个重要的缺陷,我发表了改进后的答案,以供那些寻找正确答案的新手参考:

foreach (array_filter(glob('/Path/To/*'), 'is_file') as $file)
{
    // Do something with $file
}
  1. 使用is_fileglobe函数的结果进行过滤是必要的,因为它可能会返回一些目录。
  2. 并不是所有文件名中都有.,所以*/*模式一般是不好的。

这是一个对我有效的干净执行。以前的答案显示了我不想要的结果目录。 - AWP
您需要更多的赞!实际上(在Windows上),我必须使用basename($file)来仅获取文件名,而不是包含文件名的整个路径。 - Pauloco
OP没有提到他对“目录”不感兴趣,而且目录也是文件。如果您还想要子文件夹中的文件,您必须使用is_dir并创建一个调用自身的函数。 - user281681

18

你需要用括号将$file = readdir($handle)包围起来。

下面是正确写法:

$log_directory = 'your_dir_name_here';

$results_array = array();

if (is_dir($log_directory))
{
        if ($handle = opendir($log_directory))
        {
                //Notice the parentheses I added:
                while(($file = readdir($handle)) !== FALSE)
                {
                        $results_array[] = $file;
                }
                closedir($handle);
        }
}

//Output findings
foreach($results_array as $value)
{
    echo $value . '<br />';
}

16

只需使用 glob('*')。这里是文档


14

我有更短的代码可以完成这个任务:

$path = "Pending2Post/";
$files = scandir($path);
foreach ($files as &$value) {
    echo "<a href='http://localhost/".$value."' target='_blank' >".$value."</a><br/><br/>";
}

返回给我除了两个垃圾文件“.”和“..”之外的所有文件。我的目录中没有任何名为“.”和“..”的文件。 - kamranbhatti585
1
使用 $files = array_diff(scandir($path), array('.', '..')); 来解决我所讨论的错误。 - kamranbhatti585
不错。我怎样才能移除文件的扩展名呢?(我需要移除每个文件的“.php”扩展名。) - KSPR
这是最优雅的解决方案,至少对于我想要的用途来说。 - Talha Imam

9

在一些操作系统中,你会得到 . .. 以及 .DS_Store 这些文件,我们不能使用它们,所以让我们把它们隐藏起来。

首先,使用 scandir() 获取所有文件的信息。

// Folder where you want to get all files names from
$dir = "uploads/";

/* Hide this */
$hideName = array('.','..','.DS_Store');    

// Sort in ascending order - this is default
$files = scandir($dir);
/* While this to there no more files are */
foreach($files as $filename) {
    if(!in_array($filename, $hideName)){
       /* echo the name of the files */
       echo "$filename<br>";
    }
}

4
由于运算符优先级的问题,建议将代码改为以下形式:
while(($file = readdir($handle)) !== FALSE)
{
    $results_array[] = $file;
}
closedir($handle);

2

glob()FilesystemIterator 示例:

/* 
 * glob() examples
 */

// get the array of full paths
$result = glob( 'path/*' );

// get the array of file names
$result = array_map( function( $item ) {
    return basename( $item );
}, glob( 'path/*' ) );


/* 
 * FilesystemIterator examples
 */

// get the array of file names by using FilesystemIterator and array_map()
$result = array_map( function( $item ) {
    // $item: SplFileInfo object
    return $item->getFilename();
}, iterator_to_array( new FilesystemIterator( 'path' ), false ) );

// get the array of file names by using FilesystemIterator and iterator_apply() filter
$it = new FilesystemIterator( 'path' );
iterator_apply( 
    $it, 
    function( $item, &$result ) {
        // $item: FilesystemIterator object that points to current element
        $result[] = (string) $item;
        // The function must return TRUE in order to continue iterating
        return true;
    }, 
    array( $it, &$result )
);

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接