开发者

How do I list a directory with php to navigate through folders, without javascript? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. 开发者_StackOverflow Closed 11 years ago.

I am looking for this PHP function:

  • List a directory, recursive
  • The functionallity to navigate through folders
  • No javascript
  • Navigation via web adress, "?p=2|1" or something like that
  • Sorted by type then names


<?php
class DirTree
{
    protected $root;
    protected $active;
    const URL_KEY = 'el';

    public function __construct($root, $active = null) {
        $this->root = realpath($root);

        if ($active !== null) {
            $this->active = realpath($this->root . '/' . $active);
        }
    }

    public function isActive($element) {
        return substr($this->active, 0, strlen($element->getPathname())) === $element->getPathname();
    }

    public function getLink($element) {
        return '?' . http_build_query(array(
            self::URL_KEY => substr($element->getPathname(), strlen($this->root))
        ));
    }

    protected function _get(Iterator $it) {
        $result = array();

        $dirs = $files = array();
        foreach ($it as $entry) {
            if ($entry->isDir()) {
                $data = (object)array(
                    'type' => 'dir',
                    'name' => $entry->getBasename(),
                    'object' => $entry
                );

                if ($this->isActive($entry)) {
                    $data->children = $this->_get($it->getChildren());
                    $data->active = true;
                }

                $dirs[$entry->getBasename()] = $data;
            }
            else {
                $files[$entry->getFilename()] = (object)array(
                    'type' => 'file',
                    'name' => $entry->getFilename(),
                    'object' => $entry,
                    'active' => $this->isActive($entry)
                );
            }
        }

        uksort($dirs, 'strnatcmp');
        uksort($files, 'strnatcmp');

        return array_values(array_merge($dirs, $files));
    }

    public function get() {
        return $this->_get(
            new RecursiveDirectoryIterator($this->root)
        );
    }

    public function outputUl($dirTree = null) {
        if ($dirTree === null) {
            $dirTree = $this->get();
        }

        echo '<ul>';
        foreach ($dirTree as $element) {
            $classes = array($element->type);

            if ($element->type === 'dir') {
                if ($element->active) {
                    $classes[] = 'active';
                }

                echo '<li class="', implode(' ', $classes), '">';
                echo '<a href="', $this->getLink($element->object),'">';
                echo $element->name;
                echo '</a>';
                if (sizeof($element->children) > 0) {
                    $this->outputUl($element->children);
                }
                echo '</li>';
            }
            else {
                if ($element->active) {
                    $classes[] = 'active';
                }           

                echo '<li class="', implode(' ', $classes), '">';
                echo '<a href="', $this->getLink($element->object),'">';
                echo $element->name;
                echo '</a>';
                echo '</li>';
            }
        }

        echo '</ul>';
    }
}
?>

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>DirTree</title>
        <style type="text/css">
            #dirTree a {
                text-decoration: none;
                color: #171717;
            }

            #dirTree .file a {
                color: #999999;
            }

            #dirTree .active > a {
                font-weight: bold;
            }
        </style>
    </head>

    <body>
        <div id="dirTree">
            <?php
                $dirTree = new DirTree(
                    '.',
                     isset($_GET[DirTree::URL_KEY]) ? $_GET[DirTree::URL_KEY] : null
                );
                $dirTree->outputUl();
            ?>
        </div>
    </body>
</html>


I recently had to make something like it, so here is a function that does exactly that. Optionally, you can add classnames to files and folders to style them with CSS. All folders are displayed 'opened', although with a little JS you can make a function to add some 'open-close' behaviour to the list.

<?php
/**
 * function makeDirectoryTree
 * iterates recursively through a directory
 * and lists it in an unordered list
 * 
 * usage: echo makeDirectoryTree(relative/path/to/directory);
 * 
 * @param string $pathname
 * @return string
 */
function makeDirectoryTree($pathname){
   $path = realpath($pathname);

   if(!is_dir($path)){
      return "Path does not exist!";
   }

   $foldertree = new DOMDocument();

   /*
    * the rootelement of the tree 
    */
   $ul[""] = $foldertree->createElement('ul');
   $ul[""]->setAttribute('id', 'foldertree_root');
   $foldertree->appendChild($ul[""]);

   /*
    * Files in rootfolder
    * if not iterated separately, these files will appear alphabetically between the folders
    * instead of on top of the list
    *
    */
   $iterator = new DirectoryIterator($path);
   foreach ($iterator as $fileinfo) {
      if ($fileinfo->isFile()) {
         /*
          * the random id could be useful if you want to manipulate an element with JS
          * for instance to 'open' or 'close' the folders
          * also, add an optional classname to files and folders, so you can
          * do some markup with CSS, for instance:
          * .folder {color: #f00; list-style-image: url('path/to/images/folder.png');}
          * .file {color: #999; list-style-image: url('path/to/images/file.png');}
          */
         $random_id = md5(microtime());
         $li_element = $foldertree->createElement('li', $fileinfo->getFilename());
         $li_element->setAttribute('id', 'li_' . str_ireplace(' ', '', $random_id));
         $li_element->setAttribute('class', 'file'); //optional classname
         $ul[""]->appendChild($li_element);
      }
   }

   /*
    * iterate through the other folders
    */
   $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);

   foreach($objects as $name=>$value){
      if($value->isDir()){
         $relative_path = str_ireplace($path . DIRECTORY_SEPARATOR, "", $value->getPathname());
         $path_array = explode(DIRECTORY_SEPARATOR, $relative_path);

         $new_dir = array_pop($path_array);
         $directory_up = implode(DIRECTORY_SEPARATOR, $path_array);

         $random_id = md5(microtime());

         $li[$relative_path] = $foldertree->createElement('li', $new_dir);
         $li[$relative_path]->setAttribute('id', 'li_' . str_ireplace(' ', '', $random_id));
         $li[$relative_path]->setAttribute('class', 'folder'); //optional classname

         $ul[$relative_path] = $foldertree->createElement('ul');
         $ul[$relative_path]->setAttribute('id', 'ul_' . str_ireplace(' ', '', $random_id));

         $li[$relative_path]->appendChild($ul[$relative_path]);
         $ul[$directory_up]->appendChild($li[$relative_path]);

         $iterator = new DirectoryIterator($value->getPathname());
         foreach ($iterator as $fileinfo) {
            if ($fileinfo->isFile()) {
               $random_id = md5(microtime());
               $li_element = $foldertree->createElement('li', $fileinfo->getFilename());
               $li_element->setAttribute('id', 'li_' . str_ireplace(' ', '', $random_id));
               $li_element->setAttribute('class', 'file'); //optional classname
               $ul[$relative_path]->appendChild($li_element);
            }
         }
      }
   }

   return $foldertree->saveHTML();
}
?>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜