PHP: How to populate a directory structure in an array

帅比萌擦擦* 提交于 2019-11-30 17:25:26

问题


I am developing an admin panel that shows the directory structure of a specific location on server. I have got a recursive php function that iterates through every file and folder there is. What I can't figure out is how can I store this directory structure in a php associative array like this:

array[foldername1][0]=file; // if the foldername1 contains a file
array[foldername1][foldername2][0]=file //if foldername1 contains another folder(foldername2) along with the file.

The rule i am trying to follow is; a folder should always be a key and file should always be at an index like this:

array[folder1][folder2][0]=file1;
array[folder1][folder2][1]=file2;

The function to populate this associative array should be generic as we never know what the directory structure can be. I want to json_encode this array back to my client and deal with it in javascript which is not a problem at the moment.

If this is a bad approach please let me know cauze there might be a better way to do this. I thought of using a flat array but i guess its a bad design.


回答1:


$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__), RecursiveIteratorIterator::CHILD_FIRST);
$r = array();
foreach ($ritit as $splFileInfo) {
   $path = $splFileInfo->isDir()
         ? array($splFileInfo->getFilename() => array())
         : array($splFileInfo->getFilename());

   for ($depth = $ritit->getDepth() - 1; $depth >= 0; $depth--) {
       $path = array($ritit->getSubIterator($depth)->current()->getFilename() => $path);
   }
   $r = array_merge_recursive($r, $path);
}

print_r($r);



回答2:


This class to grab files and directories recursive (= incl. subdirs) by putting the paths in a single, usable array will give you a good headstart:

  class myRecursiveDirectoryParser
  {
     protected $currentPath;
     protected $slash;
     protected $rootPath;
     protected $recursiveTree;

     function __construct($rootPath,$win=false)
     {
        switch($win)
        {
           case true:
              $this->slash = '\\';
              break;
           default:
              $this->slash = '/';
        }
        $this->rootPath = $rootPath;
        $this->currentPath = $rootPath;
        $this->recursiveTree = array(dir($this->rootPath));
        $this->rewind();
     }

     function __destruct()
     {
        $this->close();
     }

     public function close()
     {
        while(true === ($d = array_pop($this->recursiveTree)))
        {
           $d->close();
        }
     }

     public function closeChildren()
     {
        while(count($this->recursiveTree)>1 && false !== ($d = array_pop($this->recursiveTree)))
        {
           $d->close();
           return true;
        }
        return false;
     }

     public function getRootPath()
     {
        if(isset($this->rootPath))
        {
           return $this->rootPath;
        }
        return false;
     }

     public function getCurrentPath()
     {
        if(isset($this->currentPath))
        {
           return $this->currentPath;
        }
        return false;
     }

     public function read()
     {
        while(count($this->recursiveTree)>0)
        {
           $d = end($this->recursiveTree);
           if((false !== ($entry = $d->read())))
           {
              if($entry!='.' && $entry!='..')
              {
                 $path = $d->path.$entry;

                 if(is_file($path))
                 {
                    return $path;
                 }
                 elseif(is_dir($path.$this->slash))
                 {
                    $this->currentPath = $path.$this->slash;
                    if($child = @dir($path.$this->slash))
                    {
                       $this->recursiveTree[] = $child;
                    }
                 }
              }
           }
           else
           {
              array_pop($this->recursiveTree)->close();
           }
        }
        return false;
     }

     public function rewind()
     {
        $this->closeChildren();
        $this->rewindCurrent();
     }

     public function rewindCurrent()
     {
        return end($this->recursiveTree)->rewind();
     }
  }

Next up comes an example of how to use the class. In your case, you would have to walk the data, use "explode('/')" in the loop and construct a new array as you've described above.

  $d = new myRecursiveDirectoryParser("./",false);
  echo($d->getRootPath() . "<br>");
  while (false !== ($entry = $d->read())) {
     echo($entry."<br>");
  }
  $d->close();

All you need to do is get busy. You're almost done when you take it from here. ;)




回答3:


You could try this, where $dir is a specified path:

function dir_tree($dir) {
   $path = '';
   $stack[] = $dir;
   while ($stack) {
       $thisdir = array_pop($stack);
       if ($dircont = scandir($thisdir)) {
           $i=0;
           while (isset($dircont[$i])) {
               if ($dircont[$i] !== '.' && $dircont[$i] !== '..') {
                   $current_file = "{$thisdir}/{$dircont[$i]}";
                   if (is_file($current_file)) {
                       $path[] = "{$thisdir}/{$dircont[$i]}";
                   } elseif (is_dir($current_file)) {
                        $path[] = "{$thisdir}/{$dircont[$i]}";
                       $stack[] = $current_file;
                   }
               }
               $i++;
           }
       }
   }
   return $path;
}



回答4:


I've made a gist of a build tree class. It uses RecursiveDirectoryIterator and produce an array or a JSON for ajax purpose.

Here it is: https://gist.github.com/jonataswalker/3c0c6b26eabb2e36bc90



来源:https://stackoverflow.com/questions/8479543/php-how-to-populate-a-directory-structure-in-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!