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!