I\'m trying to put some folders on my hard-drive into an array.
For instance, vacation pictures. Let\'s say we have this structure:
Based on the code of @soulmerge's answer. I just removed some nits and the comments and use $startpath
as my starting directory. (THANK YOU @soulmerge!)
function dirToArray($dir) {
$contents = array();
foreach (scandir($dir) as $node) {
if ($node == '.' || $node == '..') continue;
if (is_dir($dir . '/' . $node)) {
$contents[$node] = dirToArray($dir . '/' . $node);
} else {
$contents[] = $node;
}
}
return $contents;
}
$r = dirToArray($startpath);
print_r($r);
I recommend using DirectoryIterator to build your array
Here's a snippet I threw together real quick, but I don't have an environment to test it in currently so be prepared to debug it.
$fileData = fillArrayWithFileNodes( new DirectoryIterator( '/path/to/root/' ) );
function fillArrayWithFileNodes( DirectoryIterator $dir )
{
$data = array();
foreach ( $dir as $node )
{
if ( $node->isDir() && !$node->isDot() )
{
$data[$node->getFilename()] = fillArrayWithFileNodes( new DirectoryIterator( $node->getPathname() ) );
}
else if ( $node->isFile() )
{
$data[] = $node->getFilename();
}
}
return $data;
}
A simple implementation without any error handling:
function dirToArray($dir) {
$contents = array();
# Foreach node in $dir
foreach (scandir($dir) as $node) {
# Skip link to current and parent folder
if ($node == '.') continue;
if ($node == '..') continue;
# Check if it's a node or a folder
if (is_dir($dir . DIRECTORY_SEPARATOR . $node)) {
# Add directory recursively, be sure to pass a valid path
# to the function, not just the folder's name
$contents[$node] = dirToArray($dir . DIRECTORY_SEPARATOR . $node);
} else {
# Add node, the keys will be updated automatically
$contents[] = $node;
}
}
# done
return $contents;
}
I've had success with the PEAR File_Find package, specifically the mapTreeMultiple() method. Your code would become something like:
require_once 'File/Find.php';
$fileList = File_Find::mapTreeMultiple($dirPath);
This should return an array similar to what you're asking for.
So 6 years later....
I needed a solution like the answers by @tim & @soulmerge. I was trying to do bulk php UnitTest templates for all of the php files in the default codeigniter folders.
This was step one in my process, to get the full recursive contents of a directory / folder as an array. Then recreate the file structure, and inside the directories have files with the proper name, class structure, brackets, methods and comment sections ready to fill in for the php UnitTest.
To summarize: give a directory name, get a single layered array of all directories within it as keys and all files within as values.
I expanded a their answer a bit further and you get the following:
function getPathContents($path)
{
// was a file path provided?
if ($path === null){
// default file paths in codeigniter 3.0
$dirs = array(
'./models',
'./controllers'
);
} else{
// file path was provided
// it can be a comma separated list or singular filepath or file
$dirs = explode(',', $path);
}
// final array
$contents = array();
// for each directory / file given
foreach ($dirs as $dir) {
// is it a directory?
if (is_dir($dir)) {
// scan the directory and for each file inside
foreach (scandir($dir) as $node) {
// skip current and parent directory
if ($node === '.' || $node === '..') {
continue;
} else {
// check for sub directories
if (is_dir($dir . '/' . $node)) {
// recursive check for sub directories
$recurseArray = getPathContents($dir . '/' . $node);
// merge current and recursive results
$contents = array_merge($contents, $recurseArray);
} else {
// it a file, put it in the array if it's extension is '.php'
if (substr($node, -4) === '.php') {
// don'r remove periods if current or parent directory was input
if ($dir === '.' || $dir === '..') {
$contents[$dir][] = $node;
} else {
// remove period from directory name
$contents[str_replace('.', '', $dir)][] = $node;
}
}
}
}
}
} else {
// file name was given
$contents[] = $dir;
}
}
return $contents;
}