PHP获取路径文件夹/子文件夹中的所有文件到数组? [英] PHP get path to every file in folder/subfolder into array?

查看:155
本文介绍了PHP获取路径文件夹/子文件夹中的所有文件到数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:结果
  <一href=\"http://stackoverflow.com/questions/2418068/php-spl-recursivedirectoryiterator-recursiveiteratoriterator-retrieving-the-full\">PHP SPL RecursiveDirectoryIterator RecursiveIteratorIterator检索满树

我不知道从哪里开始。但是,我必须得到一个文件夹和路径的子文件夹过的所有内容在路径中的所有文件。例如,如果我有1文件夹中有五个文件夹和每个文件夹有它等10 ... MP3音乐这意味着我的数组会找到50路到这些文件。

I am not sure where to start. But I have to get the paths to all files in a folder and all the content of the subfolder in paths too. For example if I had 1 folder that had five folders and each folder had 10 mp3s in it etc... That means my array would have to find 50 paths to these files.

后来可以说,我增加了一个文件夹,它在这3个文件夹和每个文件夹有10张图像。

Later lets say I added one more folder and it had 3 folders in it and each folder had 10 images.

我的code现在需要找到80路,并将其存储在数组中。

My code would now need to find 80 paths and store them in an array.

请问我的问题有意义吗?

Does my question make sense?

更新:

我的期望了放将具有存储在一个阵列中的所有这些路径。

My desired out put would be to have all these paths stored in one array.

不过,我会LOVE的code是动态的,这意味着如果我以后添加10个文件夹,每个有17子文件夹,具有不同内容的多种每个文件夹。我想数组来保存所有文件的文件路径。我HPPE这是有道理的。

But I would "LOVE" the code to be dynamic, meaning if I later add 10 more folder and each having 17 subfolder and each folder having a multitude of different content. I would like the array to hold the file paths of all the files. I hppe this makes sense.

推荐答案

你所寻找的是也叫的递归遍历目录的。这意味着,你正在经历的所有目录,并列出子目录和文件在那里。如果它被遍历以及等等等等子目录 - 所以它是递归的

What you are looking for is also called recursive directory traversing. Which means, you're going through all directories and list subdirectories and files in there. If there is a subdirectory it is traversed as well and so on and so forth - so it is recursive.

你可以想象这是有点当你写一个软件,你需要和PHP支持你与常见的事。它提供有一个 RecursiveDirectoryIterator 这样的目录可以递归迭代和标准 RecursiveIteratorIterator 做遍历。然后,您可以轻松地访问所有文件和目录用一个简单的迭代,例如,通过的foreach

As you can imagine this is somewhat a common thing you need when you write a software and PHP supports you with that. It offers one RecursiveDirectoryIterator so that directories can be recursively iterated and the standard RecursiveIteratorIterator to do the traversal. You can then easily access all files and directories with a simple iteration, for example via foreach:

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

这个例子首先指定要遍历目录。我一直在服用当前的:

This example first of all specifies the directory you want to traverse. I've been taking the current one:

$rootpath = '.';

code的下一行是有点长,但它确实实例目录迭代器,然后的the迭代器迭代器从而使树形结构可以在单个/平的循环来遍历:

The next line of code is a little bit long, it does instantiate the directory iterator and then the iterator-iterator so that the tree-like structure can be traversed in a single/flat loop:

$fileinfos = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootpath)
);

这些 $ fileinfos 然后用重复一个简单的的foreach

These $fileinfos are then iterated with a simple foreach:

foreach($fileinfos as $pathname => $fileinfo) {

里面的话,有一个测试,被输出跳过所有目录。这是通过使用 SplFileInfo 是迭代对象来完成。它是由递归迭代目录提供,处理文件时,包含了很多有用的属性和方法。您可以同时例如返回文件扩展名,关于大小和时间等等等等基名信息。

Inside of it, there is a test to skip all directories from being output. This is done by using the SplFileInfo object that is iterated over. It is provided by the recursive directory iterator and contains a lot of helpful properties and methods when working with files. You can as well for example return the file extension, the basename information about size and time and so on and so forth.

if (!$fileinfo->isFile()) continue;

最后,我只输出的路径的就是该文件的完整路径:

Finally I just output the pathname that is the full path to the file:

var_dump($pathname);

这是典型的输出应该是这样的(这里是Windows操作系统上):

An exemplary output would look like this (here on a windows operating system):

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

If there is a subdirectory that is not accessible, the following would throw an exception. This behaviour can be controlled with some flags when instantiating the RecursiveIteratorIterator:

$fileinfos = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator('.'),
    RecursiveIteratorIterator::LEAVES_ONLY,
    RecursiveIteratorIterator::CATCH_GET_CHILD
);

我希望这是翔实。您也可以总结这件事到一个类你自己的,你也可以提供一个 FilterIterator 来移动一个文件是否应该上市还是决定不出去了<$ C的$ C>的foreach 循环。

I hope this was informative. You can also Wrap this up into a class of your own and you can also provide a FilterIterator to move the decision whether a file should be listed or not out of the foreach loop.

RecursiveDirectoryIterator RecursiveIteratorIterator 组合的力量散发出来的灵活性。上面有什么不涵盖的所谓 FilterIterator 秒。我想我补充一点,是利用两个自写他们,放入对方把它们结合起来的另一个例子。

The power of the RecursiveDirectoryIterator and RecursiveIteratorIterator combination comes out of its flexibility. What was not covered above are so called FilterIterators. I thought I add another example that is making use of two self-written of them, placed into each other to combine them.


  • 一个是过滤掉以点开始(那些被认为是在UNIX系统中的隐藏文件,所以你不应该放弃这些信息外),所有的文件和目录

  • 另外一个是过滤列表的文件。这是检查previously是的 的内部的foreach。

  • One is to filter out all files and directories that start with a dot (those are considered hidden files on UNIX systems so you should not give that information to the outside) and
  • Another one that is filtering the list to files only. That is the check that previously was inside the foreach.

在此使用示例的另一个变化是利用的<一个href=\"http://www.php.net/recursivedirectoryiterator.getsubpathname.php\"><$c$c>getSubPathname()函数返回从迭代的ROOTPATH​​启动子路径,所以你要找的人。

Another change in this usage example is to make use of the getSubPathname() function that returns the subpath starting from the iteration's rootpath, so the one you're looking for.

此外,我明确地添加<一个href=\"http://php.net/class.filesystemiterator#filesystemiterator.constants.unix-paths\"><$c$c>SKIP_DOTS标志其中prevents穿越 .. (技术上没有的真正必要的,因为他们是目录过滤器将过滤那些为好,但我认为这是比较正确的),并作为返回路径,<一个href=\"http://php.net/class.filesystemiterator#filesystemiterator.constants.skip-dots\"><$c$c>UNIX_PATHS这样的路径字符串是不管底层操作系统这通常是一个好主意,如果通过HTTP请求这些值后来随着你的情况总是Unix类路径:

Also I explicitly add the SKIP_DOTS flag which prevents traversing . and .. (technically not really necessary because the filters would filter those as well as they are directories, however I think it is more correct) and return as paths as UNIX_PATHS so the strings of paths are always unix-like paths regardless of the underlying operating system Which is normally a good idea if those values are requested via HTTP later as in your case:

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

这例子是类似previous 1虽然在 $ fileinfos 是构建是一个怎么有点不同的配置。尤其是关于过滤器的部分是新的:

This example is similar to the previous one albeit how the $fileinfos is build is a little differently configured. Especially the part about the filters is new:

    new FilesOnlyFilter(
        new VisibleOnlyFilter(
            new RecursiveDirectoryIterator($rootpath, ...)
        )
    ),

所以目录迭代被放入过滤器和过滤器自身被放入另一个滤波器。其余未发生变化。

So the directory iterator is put into a filter and the filter itself is put into another filter. The rest did not change.

在code这些滤波器是pretty直线前进,他们用接受函数,或者是真正这是采取或过滤掉:

The code for these filters is pretty straight forward, they work with the accept function that is either true or false which is to take or to filter out:

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();
    }
}

和一遍而已。当然,你可以使用这些过滤器的其他情况下,太。例如。如果你有另一种目录列表。

And that's it again. Naturally you can use these filters for other cases, too. E.g. if you have another kind of directory listing.

和另一典型输出 $ 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

No more .git or .svn directory traversal or listing of files like .builtpath or .project.

注意的 FilesOnlyFilter LEAVES_ONLY
  <子>
  该过滤器明确否认使用目录中的的基于 SplFileInfo 对象链接(的只有确实存在常规文件)。因此,它是基于文件系统上的实际滤波。结果
  只能获得非目录的另一种方法条目船,因为默认的 RecursiveIteratorIterator
。 construct.php> LEAVES_ONLY 标志(这里使用过的例子)。此标志不工作作为过滤器,并独立于底层的迭代器。它只是指定了迭代不应该返回枝条。(这里:的目录中的迭代器的情况下,目录)

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获取路径文件夹/子文件夹中的所有文件到数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆