【问题标题】:How do I list a directory with php to navigate through folders, without javascript? [closed]如何在没有 javascript 的情况下使用 php 列出目录以浏览文件夹? [关闭]
【发布时间】:2011-05-04 09:30:12
【问题描述】:

我正在寻找这个 PHP 函数:

  • 列出目录,递归
  • 浏览文件夹的功能
  • 没有javascript
  • 通过网址导航,“?p=2|1”或类似的东西
  • 先按类型再按名称排序

【问题讨论】:

  • 这是一个很大的问题。通过将其分解为组件,您将获得更好的响应。 (如何列出文件夹的内容?如何使用锚标记更改工作目录?等等等等)
  • 只是让 url 分页与目录树列表一起工作将是一个关键。其余的可能更容易解决。
  • 这不是一个“让我成为 PHP 应用程序”的网站。

标签: php treeview tree navigation directory


【解决方案1】:
<?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>

【讨论】:

  • @Yoshi 是的,但我希望父母始终可见。
  • @Peter 查看更新,但仍有很多工作要做。但我认为作为一个例子就足够了。
  • @Yoshi 令人印象深刻。这么小的代码,这么多的功能。糟糕的是,我自己并不能理解一切。但是,获得按我想要的方式运行的功能代码是一种很好的感觉。经过几天的混乱。 “RecursiveDirectoryIterator”一定是某个内置的php类?
  • @Peter 是的,它带有 SPL,看看:php.net/manual/en/book.spl.phpphp.net/manual/en/spl.iterators.php
  • @Yoshi 如何让printf('&lt;li&gt;&lt;a href="?dir=%s/%2$s"&gt;%2$s&lt;/a&gt;', implode('/', $parents), $entry-&gt;getBasename()); 成为回声?希望代码对我自己更容易理解。
【解决方案2】:

我最近不得不制作类似的东西,所以这里有一个功能可以做到这一点。或者,您可以将类名添加到文件和文件夹以使用 CSS 设置它们的样式。 所有文件夹都显示为“打开”,尽管使用一点 JS,您可以创建一个函数来将一些“打开-关闭”行为添加到列表中。

<?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();
}
?>

【讨论】:

  • 但问题是我不想想使用 JS。而且我不希望所有文件夹都显示为已打开。
  • 我在之前的评论中忘记了你的名字。不知道这是否重要...希望得到帮助。
  • @Peter 没问题,有什么可以帮忙的吗?
猜你喜欢
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多