简体   繁体   English

将目录中的所有子目录和文件递归添加到数组中

[英]Recursively adding all sub directories and files from a directory into an array

I have a function that will obtain all directories and files from a given directory, however the way it obtains them makes it a little more complicated to work with: 我有一个将从给定目录中获取所有目录和文件的函数,但是它获取它们的方式使使用它变得更加复杂:

function getFileLists($dir, $recursive=FALSE) {
    // retrieve an array of all the directories and files in a certain directory
    $retval = [];
    if (substr($dir, -1) !== "/") {
        $dir .= "/";
    }
    $d = @dir($dir) or die("unable to open {$dir} for reading, permissions?");
    while(FALSE !== ($entry = $d->read())) {
        if ($entry{0} === ".") { continue; }
        if (is_dir("{$dir}{$entry}")) {
            $retval[] = [
                'name' => "{$dir}{$entry}",
                'last_modified' => filemtime("{$dir}{$entry}")
            ];
            if($recursive && is_readable("{$dir}{$entry}/")) {
                $retval = array_merge($retval, getFileLists("{$dir}{$entry}/", TRUE));
            }
        } elseif (is_readable("{$dir}{$entry}")) {
            $retval[] = [
                'name' => "{$dir}{$entry}",
                'last_modified' => filemtime("{$dir}{$entry}")
            ];
        }
    }
    $d->close();
    return $retval;
}

When you run this on a given directory it will produce the following results: 在给定目录上运行此命令时,将产生以下结果:

array(14) {
  [0]=>
  array(2) {
    ["name"]=>
    string(15) "./kb_data/admin"
    ["last_modified"]=>
    int(1543591247)
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(28) "./kb_data/admin/testfile.txt"
    ["last_modified"]=>
    int(1543591238)
  }
  ...
}

Which is great but this makes it pretty difficult to work with seeing as how I want to display this directory as a tree . 很棒,但这使我很难以我希望将此目录显示为tree What I'm actually wanting to do is the produce something along the lines of the following: 我实际上想要做的是根据以下内容进行生产:

array(14) {
  [0]=>
    array(3) {
    ["name"]=>
    string(16) "./kb_data/shared"
    ["last_modified"]=>
    int(1543591258)
    ["files"] => array(#) {
        ["name"]=>
        string(29) "./kb_data/shared/testfile.txt"
        ["last_modified"]=>
        int(1543591238)
     }
  }
  ...
}

As you can see, I want each file thats in the directory to be inside of the directory. 如您所见,我希望目录中的每个文件都在目录内。 How can I go about refactoring this function in order to obtain the output I desire? 我该如何重构该函数以获得所需的输出?

What about (SPL) Directory Iterator 关于(SPL)目录迭代器

function getFileLists($dir) {
    $rec = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::SELF_FIRST);
    $ar = array();
    foreach ($rec as $splFileInfo) {
       $path = $splFileInfo->isDir()
             ? array($splFileInfo->getFilename() => array())
             : array($splFileInfo->getFilename());

       for ($depth = $rec->getDepth() - 1; $depth >= 0; $depth--) {
           $path = array($rec->getSubIterator($depth)->current()->getFilename() => $path);
       }
       $ar = array_merge_recursive($ar, $path);
    }
    return $ar;
}
print "<pre>";
print_r(getFileLists("/Library/WebServer/Documents/am-web/"));

Personally I like to keep it simple, plucked this one out of my personal library, possible not the best answer but it get the trick done 就我个人而言,我喜欢保持简单,将其从我的个人资料库中删除,可能不是最佳答案,但可以解决问题

<?php
function glob_recursive($dir, $recursive = false) {
    $files = [];
    foreach (glob($dir  . DIRECTORY_SEPARATOR . '*') as $object) {
        if (in_array($object, ['.', '..'])) {
            continue;
        }
        $file = [];
        $file['name'] = $object;
        if (false !== $recursive && is_dir($object)) {
            $file['files'] = glob_recursive($object);
        }
        $files[] = $file;
    }
    return $files;
}
$dir = __DIR__;
$list = glob_recursive($dir);

A simple but complete example which uses DirectoryIterator to list all of the files in a directory and recursion to avoid having to mangle the recursive iterator data to give all the info required. 一个简单但完整的示例,该示例使用DirectoryIterator列出目录中的所有文件并进行递归,以避免必须处理递归迭代器数据以提供所需的所有信息。 The thing I like about DirectoryIterator is that this gives an object where you can extract a lot of the files details (such as last modified time using getMTime() ). 我喜欢DirectoryIterator在于,它提供了一个对象,您可以在其中提取许多文件的详细信息(例如,使用getMTime()修改的时间)。

function buildTree ( $path )    {
    $paths = [];
    foreach (new DirectoryIterator ($path) as $file) {
        if ( !$file->isDot() )   {
            $newFile = ["name" => $file->getRealPath(),
                "last_modified" => $file->getMTime()];
            if ($file->isDir()) {
                $newFile["files"] = buildTree($file->getRealPath());
            }
            $paths[] = $newFile;
        }
    }
    return $paths;
}
$paths = buildTree($root);

I would remove the "recursive" parameter and try something like this: 我将删除“递归”参数并尝试如下操作:

function getFileLists($dir)
{
    echo "Processing $dir\n";

    // retrieve an array of all the directories and files in a certain directory
    $retval = [];
    if (substr($dir, -1) !== "/") {
        $dir .= "/";
    }
    $d = @dir($dir) or die("unable to open {$dir} for reading, permissions?");
    while (false !== ($entry = $d->read())) {
        if ($entry{0} === ".") {
            continue;
        }
        if (is_dir("{$dir}{$entry}")) {
            $retval[] = [
                'name'          => "{$dir}{$entry}",
                'last_modified' => filemtime("{$dir}{$entry}"),
                //recursive call 
                'files'         => array_merge($retval, getFileLists("{$dir}{$entry}/"))
            ];
        } elseif (is_readable("{$dir}{$entry}")) {
            $retval[] = [
                'name'          => "{$dir}{$entry}",
                'last_modified' => filemtime("{$dir}{$entry}")
            ];
        }
    }
    $d->close();

    return $retval;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PHP:从目录和所有子目录中的文件名中递归删除括号 - PHP: recursively remove brackets from filenames in directory and all sub directories 从当前目录和子目录中检索所有文件 - Retrieve all files from current directory and sub-directories 将所有文件从子目录移动到主目录中 - Move all files from sub directories into main directory 从目录和子目录中获取数组中的所有图像 - get all images in an array from directory and sub-directories 递归将给定目录PHP或命令行中的所有文件和目录大写 - Recursively Capitalize all Files and Directories within a Given Directory PHP or Commandline 在特定时间后从目录和所有子目录中修改的PHP删除(.extension)文件 - PHP delete (.extension) files that are modified after specific time from directory and all sub-directories 递归获取目录中的所有文件,并按扩展名获取子目录 - Recursivly get all files in a directory, and sub directories by extension PHP删除目录和任何子目录中所有空文件 - PHP Delete all files that are empty in a Directory and any sub directories PHP - 仅显示目录和子目录中的PHP文件 - PHP - displaying just PHP files from a directory and sub directories 是否可以使用glob从根目录和子目录中获取文件? - is it possible to get files from a root directory and sub directories with glob?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM