PHP获取文件夹/子文件夹中每个文件的路径到数组中?

标签 php arrays multidimensional-array path directory

这个问题在这里已经有了答案:




9年前关闭。




Possible Duplicate:
PHP SPL RecursiveDirectoryIterator RecursiveIteratorIterator retrieving the full tree



我不知道从哪里开始。但是我必须获取文件夹中所有文件的路径以及路径中子文件夹的所有内容。例如,如果我有 1 个文件夹,其中有五个文件夹,每个文件夹中有 10 个 mp3 等等……这意味着我的数组必须找到这些文件的 50 个路径。

稍后可以说我又添加了一个文件夹,其中有 3 个文件夹,每个文件夹有 10 个图像。

我的代码现在需要找到 80 条路径并将它们存储在一个数组中。

我的问题有意义吗?

更新:

我想要的输出是将所有这些路径存储在一个数组中。

但我希望代码是动态的,这意味着如果我以后再添加 10 个文件夹,每个文件夹都有 17 个子文件夹,每个文件夹都有许多不同的内容。我希望数组保存所有文件的文件路径。我认为这是有道理的。

最佳答案

您正在寻找的也称为递归目录遍历。这意味着,您将浏览所有目录并列出其中的子目录和文件。如果有一个子目录,它也会被遍历等等——所以它是递归的。

正如您可以想象的那样,当您编写软件并且 PHP 支持您时,这在某种程度上是您需要的常见事情。它提供了一个 RecursiveDirectoryIterator以便目录可以递归迭代和标准 RecursiveIteratorIterator做遍历。然后,您可以通过简单的迭代轻松访问所有文件和目录,例如通过 foreach :

$rootpath = '.';
$fileinfos = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootpath)
);
foreach($fileinfos as $pathname => $fileinfo) {
    if (!$fileinfo->isFile()) continue;
    var_dump($pathname);
}

这个例子首先指定了你要遍历的目录。我一直在服用当前的:
$rootpath = '.';

下一行代码有点长,它确实实例化了 the directory iterator然后 the iterator-iterator以便可以在单个/平面循环中遍历树状结构:
$fileinfos = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootpath)
);

这些 $fileinfos然后用一个简单的 foreach 迭代:
foreach($fileinfos as $pathname => $fileinfo) {

在其中,有一个测试可以跳过所有目录的输出。这是通过使用 SplFileInfo 来完成的。被迭代的对象。它由递归目录迭代器提供,并在处理文件时包含许多有用的属性和方法。例如,您还可以返回文件扩展名、有关大小和时间的基本名称信息等等。
if (!$fileinfo->isFile()) continue;

最后,我只输出作为文件完整路径的路径名:
var_dump($pathname);

示例输出如下所示(此处为 Windows 操作系统):
string(12) ".\.buildpath"
string(11) ".\.htaccess"
string(33) ".\dom\xml-attacks\attacks-xml.php"
string(38) ".\dom\xml-attacks\billion-laughs-2.xml"
string(36) ".\dom\xml-attacks\billion-laughs.xml"
string(40) ".\dom\xml-attacks\quadratic-blowup-2.xml"
string(40) ".\dom\xml-attacks\quadratic-blowup-3.xml"
string(38) ".\dom\xml-attacks\quadratic-blowup.xml"
string(22) ".\dom\xmltree-dump.php"
string(25) ".\dom\xpath-list-tags.php"
string(22) ".\dom\xpath-search.php"
string(27) ".\dom\xpath-text-search.php"
string(29) ".\encrypt-decrypt\decrypt.php"
string(29) ".\encrypt-decrypt\encrypt.php"
string(26) ".\encrypt-decrypt\test.php"
string(13) ".\favicon.ico"

如果存在不可访问的子目录,以下将引发异常。在实例化 RecursiveIteratorIterator 时,可以使用一些标志来控制此行为。 :
$fileinfos = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator('.'),
    RecursiveIteratorIterator::LEAVES_ONLY,
    RecursiveIteratorIterator::CATCH_GET_CHILD
);

我希望这是有益的。你也可以把它打包成一个你自己的类,你也可以提供一个 FilterIterator将决定是否应列出文件移出 foreach环形。
RecursiveDirectoryIterator的力量和 RecursiveIteratorIterator组合来自其灵活性。上面没有提到的就是所谓的 FilterIterator s。我想我添加了另一个示例,该示例使用两个自己编写的示例,将它们放在一起以组合它们。
  • 一种是过滤掉所有以点开头的文件和目录(那些在 UNIX 系统上被认为是隐藏文件,所以你不应该把这些信息提供给外部)和
  • 另一个将列表过滤为仅文件。那是之前在 foreach 中的检查。

  • 此用法示例的另一个更改是使用 getSubPathname() function它返回从迭代的根路径开始的子路径,所以你正在寻找。

    我还明确添加了 SKIP_DOTS flag这可以防止遍历 ... (从技术上讲并不是真的有必要,因为过滤器会过滤它们以及它们是目录,但是我认为它更正确)并作为路径返回 UNIX_PATHS 因此,无论底层操作系统如何,路径字符串始终是类 Unix 路径,如果稍后通过 HTTP 请求这些值(如您的情况),这通常是一个好主意:
    $rootpath = '.';
    
    $fileinfos = new RecursiveIteratorIterator(
        new FilesOnlyFilter(
            new VisibleOnlyFilter(
                new RecursiveDirectoryIterator(
                    $rootpath,
                    FilesystemIterator::SKIP_DOTS
                        | FilesystemIterator::UNIX_PATHS
                )
            )
        ),
        RecursiveIteratorIterator::LEAVES_ONLY,
        RecursiveIteratorIterator::CATCH_GET_CHILD
    );
    
    foreach ($fileinfos as $pathname => $fileinfo) {
        echo $fileinfos->getSubPathname(), "\n";
    }
    

    此示例与前一个示例类似,尽管 $fileinfos build 的配置略有不同。特别是关于过滤器的部分是新的:
        new FilesOnlyFilter(
            new VisibleOnlyFilter(
                new RecursiveDirectoryIterator($rootpath, ...)
            )
        ),
    

    所以目录迭代器被放入一个过滤器,过滤器本身被放入另一个过滤器。其余没有变化。

    这些过滤器的代码非常简单,它们适用于 accept函数是 truefalse这是采取或过滤掉:
    class VisibleOnlyFilter extends RecursiveFilterIterator
    {
        public function accept()
        {
            $fileName = $this->getInnerIterator()->current()->getFileName();
            $firstChar = $fileName[0];
            return $firstChar !== '.';
        }
    }
    
    class FilesOnlyFilter extends RecursiveFilterIterator
    {
        public function accept()
        {
            $iterator = $this->getInnerIterator();
    
            // allow traversal
            if ($iterator->hasChildren()) {
                return true;
            }
    
            // filter entries, only allow true files
            return $iterator->current()->isFile();
        }
    }
    

    又是这样。当然,您也可以将这些过滤器用于其他情况。例如。如果您有另一种目录列表。

    另一个示例输出是 $rootpath切开:
    test.html
    test.rss
    tests/test-pad-2.php
    tests/test-pad-3.php
    tests/test-pad-4.php
    tests/test-pad-5.php
    tests/test-pad-6.php
    tests/test-pad.php
    TLD/PSL/C/dkim-regdom.c
    TLD/PSL/C/dkim-regdom.h
    TLD/PSL/C/Makefile
    TLD/PSL/C/punycode.pl
    TLD/PSL/C/test-dkim-regdom.c
    TLD/PSL/C/test-dkim-regdom.sh
    TLD/PSL/C/tld-canon.h
    TLD/PSL/generateEffectiveTLDs.php
    

    没有了 .git.svn目录遍历或文件列表,如 .builtpath.project .

    Note for FilesOnlyFilter and LEAVES_ONLY: The filter explicitly denies the use of directories and links based on the SplFileInfo object (only regular files that do exist). So it is a real filtering based on the file-system.
    Another method to only get non-directory entries ships with RecursiveIteratorIterator because of the default LEAVES_ONLY flag (here used too in the examples). This flag does not work as a filter and is independent to the underlying iterator. It just specifies that the iteration should not return branchs (here: directories in case of the directory iterator).

    关于PHP获取文件夹/子文件夹中每个文件的路径到数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12233859/

    相关文章:

    php - 如何使用 Kohana 生成 SEO 友好的 URL

    php - 如何使用 PHP REST API Wrapper 调用带有分机号的号码?

    php - js中将php字符串数组转换为js数组

    arrays - 有条件地实例化一个新的Perl数组

    Java 2d String数组填充数组

    javascript - 如何访问 javascript 中的 laravel .env 变量?

    arrays - 如何在 Robo3T 中将结果从一个查询传递到另一个查询

    c++ - 数组和指针

    c - 如何判断每个随机数是否命中错误

    python - 如何对 4D numpy 数组执行迭代 2D 操作