Reputation: 69
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!
Upvotes: 5
Views: 6474
Reputation: 56351
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";
}
?>
Upvotes: 0
Reputation: 95101
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)));
}
Upvotes: 10
Reputation: 12985
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!
Upvotes: 2