PHP Recursive function: Get all files and directories within a directory and its sub-directories

StackOverflow https://stackoverflow.com/questions/23198859

سؤال

I have wrote a php function, through which I want an array of all the files and directories in a particular directory.


1) Below is my directory structure -

/pages  (Full path - /home/ubuntu/projects/xyz.com/code/ciapp/views/pages)
|
|--file1.php
|--file2.php
|--file3.php
|--folder1
   |--file4.php
   |--file5.php
   |--folder2
      |--file6.php
|--folder3
   |--file7.php
   |--file8.php


2) What I want is an array of files and directories -

Array
(
[files] => Array
    (
        [0] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/file1.php
        [1] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/file2.php
        [2] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/file3.php
        [3] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder1/file4.php
        [4] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder1/file5.php
        [5] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder1/folder2/file6.php
        [6] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder3/file7.php
        [7] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder3/file8.php
    )

[directories] => Array
    (
        [0] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder1
        [1] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder1/folder2
        [2] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder3
    )
)


3) What I am getting (only 1 level) -

Array
(
[files] => Array
    (
        [0] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/file1.php
        [1] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/file2.php
        [2] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/file3.php
    )

[directories] => Array
    (
        [0] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder1
        [1] => /home/ubuntu/projects/xyz.com/code/ciapp/views/pages/folder3
    )
)


4) My function -

function get_files_directories($directory, $a = array())
{
    $dirs = scandir($directory, 1);
    $arr = $a;

    foreach($dirs as $dir)
    {
       if($dir != "." && $dir != '..')
       {
           $new_dir = $directory.'/'.$dir;
           if(is_dir($new_dir))
           {
               $arr['directories'][] = $new_dir;
               get_files_directories($new_dir, $arr);
           }
           else
           {
               $arr['files'][] = $new_dir;
           }
       }
    }

    return $arr;
}

$my_dir = "/home/ubuntu/projects/xyz.com/code/ciapp/views/pages";
$files_dirs = get_files_directories($my_dir);

echo '<pre>'; print_r($files_dirs);


What am I missing here? Help will be appreciated. Thankyou :)

هل كانت مفيدة؟

المحلول

Switch $path with your path, and this should work. The SPL contains all the classes required for recursive directory traversal, there is no need to roll your own.

<?php

$path   = '.';
$result = array('files' => array(), 'directories' => array());

$DirectoryIterator = new RecursiveDirectoryIterator($path);
$IteratorIterator  = new RecursiveIteratorIterator($DirectoryIterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($IteratorIterator as $file) {

    $path = $file->getRealPath();
    if ($file->isDir()) {
        $result['directories'][] = $path;
    } elseif ($file->isFile()) {
        $result['files'][] = $path;
    }

}

print_r($result);

For more information, consult the PHP documentation: RecursiveDirectoryIterator, RecursiveIteratorIterator & SplFileInfo are great starting points!

نصائح أخرى

Using the FilesystemIterator may be a bit faster:

function getDirectoryList($dir) {
    $dirList = $fileList = array();
    $iter = new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);

    foreach($iter as $file) {
        if($file->isDir()) {
            $dirList[$file->getFilename()] = getDirectoryList($file->getPathname());
        } else {
            $fileList[$file->getFilename()] = $file->getFilename();
        }
    }
    uksort($dirList, "strnatcmp");
    natsort($fileList);
    return $dirList + $fileList;
}

This function will give you a multi-dimensional array structured exactly like your directory structure, which may also be easier to work with.

You should either assign the "arr" returning from the recusive call OR you should pass in the array by reference. (see passing by reference: http://php.net/manual/en/language.references.pass.php)

To pass by reference: get_files_directories($new_dir, &$arr);

It's a recursive call and you might append the return value to the array or work on a array reference:

if(is_dir($new_dir))
{
    $arr['directories'][] = $new_dir;
    get_files_directories($new_dir, $arr); //assign or return
}

-

function get_files_directories($directory, &$arr) 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top