【问题标题】:PHP recursive folder scan into multi array (subfolders and files)PHP递归文件夹扫描成多数组(子文件夹和文件)
【发布时间】:2012-10-10 02:10:36
【问题描述】:

我现在有点迷路了。我的目标是递归扫描具有子文件夹和每个子文件夹中的图像的文件夹,将其放入多维数组,然后能够解析每个子文件夹及其包含的图像。

我有以下起始代码,它基本上是扫描每个包含文件的子文件夹,现在只是丢失了将它放入一个多数组中。

$dir = 'data/uploads/farbmuster';
$results = array();

if(is_dir($dir)) {
    $iterator = new RecursiveDirectoryIterator($dir);

    foreach(new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file) {
        if($file->isFile()) {
            $thispath = str_replace('\\','/',$file->getPath());
            $thisfile = utf8_encode($file->getFilename());

            $results[] = 'path: ' . $thispath. ',  filename: ' . $thisfile;
        }
    }
}

有人可以帮我解决这个问题吗?

提前致谢!

【问题讨论】:

  • 是否有特定的原因为什么您需要存储文件的数组需要是多维的?因为如果没有,你只会让事情变得困难而不是解决你的问题。
  • 是的,有一个特定的原因:我正在使用它是一个简单的 CMS,用户可以将图像动态上传到预定义的文件夹/子文件夹中。 CMS有点棘手,所以我需要调用这个函数来获取子文件夹中的所有图像来显示它。示例:然后子文件夹 1 将显示为标题及其所有包含的图像,然后下一个文件夹 2 作为标题及其包含的图像等。

    1

    Image1 Image2

    2

    图片1 图片2

标签: php recursion directory subdirectory


【解决方案1】:

如果您想获取包含子目录的文件列表,请使用(但更改文件夹名称)

<?php
$path = realpath('yourfold/samplefolder');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
        echo "$filename\n";
}
?>

【讨论】:

    【解决方案2】:

    你可以试试

    $dir = 'test/';
    $results = array();
    if (is_dir($dir)) {
        $iterator = new RecursiveDirectoryIterator($dir);
        foreach ( new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file ) {
            if ($file->isFile()) {
                $thispath = str_replace('\\', '/', $file);
                $thisfile = utf8_encode($file->getFilename());
                $results = array_merge_recursive($results, pathToArray($thispath));
            }
        }
    }
    echo "<pre>";
    print_r($results);
    

    输出

    Array
    (
        [test] => Array
            (
                [css] => Array
                    (
                        [0] => a.css
                        [1] => b.css
                        [2] => c.css
                        [3] => css.php
                        [4] => css.run.php
                    )
    
                [CSV] => Array
                    (
                        [0] => abc.csv
                    )
    
                [image] => Array
                    (
                        [0] => a.jpg
                        [1] => ab.jpg
                        [2] => a_rgb_0.jpg
                        [3] => a_rgb_1.jpg
                        [4] => a_rgb_2.jpg
                        [5] => f.jpg
                    )
    
                [img] => Array
                    (
                        [users] => Array
                            (
                                [0] => a.jpg
                                [1] => a_rgb_0.jpg
                            )
    
                    )
    
            )
    

    使用的功能

    function pathToArray($path , $separator = '/') {
        if (($pos = strpos($path, $separator)) === false) {
            return array($path);
        }
        return array(substr($path, 0, $pos) => pathToArray(substr($path, $pos + 1)));
    }
    

    【讨论】:

    • 无法正常工作。 upload/ 包含像这样的几个子文件夹中的图像文件 "users/image/2014/jun" "users/images/2014/may" 返回的数组包含:upload > users > images > 2014 > may .... upload > users > 图片 > 2015 > 可能 .... 上传 > 用户 > 图片 > 2016 > 六月 .... 2015 和 2016 不是目录,也不存在..
    【解决方案3】:

    RecursiveDirectoryIterator 以递归方式扫描到平面结构中。要创建深层结构,您需要使用 DirectoryIterator递归函数 (调用自身)。如果您当前的文件 isDir() 和 !isDot() 通过以新目录作为参数再次调用该函数来深入了解它。并将新数组附加到您当前的集合中。

    如果你不能处理这个问题,我会在这里转储一些代码。必须记录一下(现在有 ninja cmets)......

    代码

    /**
     * List files and folders inside a directory into a deep array.
     *
     * @param string $Path
     * @return array/null
     */
    function EnumFiles($Path){
        // Validate argument
        if(!is_string($Path) or !strlen($Path = trim($Path))){
            trigger_error('$Path must be a non-empty trimmed string.', E_USER_WARNING);
            return null;
        }
        // If we get a file as argument, resolve its folder
        if(!is_dir($Path) and is_file($Path)){
            $Path = dirname($Path);
        }
        // Validate folder-ness
        if(!is_dir($Path) or !($Path = realpath($Path))){
            trigger_error('$Path must be an existing directory.', E_USER_WARNING);
            return null;
        }
        // Store initial Path for relative Paths (second argument is reserved)
        $RootPath = (func_num_args() > 1) ? func_get_arg(1) : $Path;
        $RootPathLen = strlen($RootPath);
        // Prepare the array of files
        $Files = array();
        $Iterator = new DirectoryIterator($Path);
        foreach($Iterator as /** @var \SplFileInfo */ $File){
            if($File->isDot()) continue; // Skip . and ..
            if($File->isLink() or (!$File->isDir() and !$File->isFile())) continue; // Skip links & other stuff
            $FilePath = $File->getPathname();
            $RelativePath = str_replace('\\', '/', substr($FilePath, $RootPathLen));
            $Files[$RelativePath] = $FilePath; // Files are string
            if(!$File->isDir()) continue;
            // Calls itself recursively [regardless of name :)]
            $SubFiles = call_user_func(__FUNCTION__, $FilePath, $RootPath);
            $Files[$RelativePath] = $SubFiles; // Folders are arrays
        }
        return $Files; // Return the tree
    }
    

    测试它的输出并弄清楚:) 你可以做到!

    【讨论】:

    • 嗯,我对你的解释有点迷茫:)
    • @BenG 现在试试,这是我给你的最多的:) 必须学习休息。
    猜你喜欢
    • 1970-01-01
    • 2012-04-02
    • 2010-11-02
    • 2013-06-14
    • 2011-11-07
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2013-02-03
    相关资源
    最近更新 更多