5

I'm a little bit lost here at the moment. My goal is to recursive scan a folder with subfolders and images in each subfolder, to get it into a multidimensional array and then to be able to parse each subfolder with its containing images.

I have the following starting code which is basically scanning each subfolders containing files and just lost to get it into a multi array now.

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

Can someone help me with this?

Thanks in advance!

Ben G
  • 69
  • 3
  • 6
  • is there a specific reason why you need the array in which you want to store the files needs to be multidimensional? Because if there is none, you're just going to make things difficult instead of solving your problem. – MarcDefiant Oct 19 '12 at 12:55
  • Yes, there is a specific reason: it's a simple CMS which I'm using, where the user can dynamically upload images into a predefined folder/subfolder. The CMS is a bit tricky, so I need to call this function to get all images by subfolder to display it. Example: subfolder 1 will then be displayed as a header and all its containing images after that, then the next folder 2 as a header and its containing images etc.

    1

    Image1 Image2

    2

    Image1 Image2
    – Ben G Oct 19 '12 at 13:23
  • possible duplicate: http://stackoverflow.com/questions/3556781/use-recursivedirectoryiterator-to-list-directories-and-files-into-array – MarcDefiant Oct 19 '12 at 13:24

3 Answers3

10

You can try

$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);

Output

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 Used

function pathToArray($path , $separator = '/') {
    if (($pos = strpos($path, $separator)) === false) {
        return array($path);
    }
    return array(substr($path, 0, $pos) => pathToArray(substr($path, $pos + 1)));
}
Baba
  • 94,024
  • 28
  • 166
  • 217
  • Not working correctly. upload/ contains image files in few sub folders like this "users/image/2014/jun" "users/images/2014/may" the returned array contains: upload > users > images > 2014 > may .... upload > users > images > 2015 > may .... upload > users > images > 2016 > jun .... 2015 and 2016 are not dirs and do not exist.. – Braza Jun 02 '14 at 12:01
2

RecursiveDirectoryIterator scans recursively into a flat structure. To create a deep structure you need a recursive function (calls itself) using DirectoryIterator. And if your current file isDir() and !isDot() go deep on it by calling the function again with the new directory as arguments. And append the new array to your current set.

If you can't handle this holler and I'll dump some code here. Have to document (has ninja comments right now) it a bit so... trying my luck the lazy way, with instructions.

CODE:

/**
 * 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
}

Test its output and figure it out :) You can do it!

CodeAngry
  • 12,760
  • 3
  • 50
  • 57
0

If you want to get list of files with subdirectories, then use (but change the foldername)

<?php
$path = realpath('yourfold/samplefolder');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
        echo "$filename\n";
}
?>
T.Todua
  • 53,146
  • 19
  • 236
  • 237