繁体   English   中英

使用php列出目录中的所有文件夹子文件夹和文件

[英]Listing all the folders subfolders and files in a directory using php

请给我一个使用 php 列出目录中所有文件夹、子文件夹、文件的解决方案。 我的文件夹结构是这样的:

Main Dir
 Dir1
  SubDir1
   File1
   File2
  SubDir2
   File3
   File4
 Dir2
  SubDir3
   File5
   File6
  SubDir4
   File7
   File8

我想获取每个文件夹中所有文件的列表。

php中是否有任何shell脚本命令?

function listFolderFiles($dir){
    $ffs = scandir($dir);

    unset($ffs[array_search('.', $ffs, true)]);
    unset($ffs[array_search('..', $ffs, true)]);

    // prevent empty ordered elements
    if (count($ffs) < 1)
        return;

    echo '<ol>';
    foreach($ffs as $ff){
        echo '<li>'.$ff;
        if(is_dir($dir.'/'.$ff)) listFolderFiles($dir.'/'.$ff);
        echo '</li>';
    }
    echo '</ol>';
}

listFolderFiles('Main Dir');

此代码在树视图中按排序顺序列出所有目录和文件。 它是一个站点地图生成器,带有指向所有站点资源的超链接。 完整的网页来源在这里。 您需要更改从末尾算起的第九行的路径。

<?php
$pathLen = 0;

function prePad($level)
{
  $ss = "";

  for ($ii = 0;  $ii < $level;  $ii++)
  {
    $ss = $ss . "|&nbsp;&nbsp;";
  }

  return $ss;
}

function myScanDir($dir, $level, $rootLen)
{
  global $pathLen;

  if ($handle = opendir($dir)) {

    $allFiles = array();

    while (false !== ($entry = readdir($handle))) {
      if ($entry != "." && $entry != "..") {
        if (is_dir($dir . "/" . $entry))
        {
          $allFiles[] = "D: " . $dir . "/" . $entry;
        }
        else
        {
          $allFiles[] = "F: " . $dir . "/" . $entry;
        }
      }
    }
    closedir($handle);

    natsort($allFiles);

    foreach($allFiles as $value)
    {
      $displayName = substr($value, $rootLen + 4);
      $fileName    = substr($value, 3);
      $linkName    = str_replace(" ", "%20", substr($value, $pathLen + 3));
      if (is_dir($fileName)) {
        echo prePad($level) . $linkName . "<br>\n";
        myScanDir($fileName, $level + 1, strlen($fileName));
      } else {
        echo prePad($level) . "<a href=\"" . $linkName . "\" style=\"text-decoration:none;\">" . $displayName . "</a><br>\n";
      }
    }
  }
}

?><!DOCTYPE HTML>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Site Map</title>
</head>

<body>
<h1>Site Map</h1>
<p style="font-family:'Courier New', Courier, monospace; font-size:small;">
<?php
  $root = '/home/someuser/www/website.com/public';

  $pathLen = strlen($root);

  myScanDir($root, 0, strlen($root)); ?>
</p>
</body>

</html>

显示文件夹结构的一种非常简单的方法是使用RecursiveTreeIterator类(PHP 5 >= 5.3.0,PHP 7)并生成 ASCII 图形树。

$it = new RecursiveTreeIterator(new RecursiveDirectoryIterator("/path/to/dir", RecursiveDirectoryIterator::SKIP_DOTS));
foreach($it as $path) {
  echo $path."<br>";
}

http://php.net/manual/en/class.recursivetreeiterator.php

通过使用RecursiveTreeIterator::setPrefixPart更改前缀,还可以对树的 ASCII 表示进行一些控制,例如$it->setPrefixPart(RecursiveTreeIterator::PREFIX_LEFT, "|");

如果您想使用directoryIterator

以下函数是使用directoryIterator重新实现 @Shef 答案

function listFolderFiles($dir)
{
    echo '<ol>';
    foreach (new DirectoryIterator($dir) as $fileInfo) {
        if (!$fileInfo->isDot()) {
            echo '<li>' . $fileInfo->getFilename();
            if ($fileInfo->isDir()) {
                listFolderFiles($fileInfo->getPathname());
            }
            echo '</li>';
        }
    }
    echo '</ol>';
}
listFolderFiles('Main Dir');

我真的很喜欢 SPL 库,他们提供迭代器,包括RecursiveDirectoryIterator

它将用于以目录格式制作菜单栏

$pathLen = 0;

function prePad($level)
{
  $ss = "";

  for ($ii = 0;  $ii < $level;  $ii++)
  {
      $ss = $ss . "|&nbsp;&nbsp;";
    }

    return $ss;
  }

  function myScanDir($dir, $level, $rootLen)
  {
    global $pathLen;

    if ($handle = opendir($dir)) {

      $allFiles = array();

      while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {
          if (is_dir($dir . "/" . $entry))
          {
            $allFiles[] = "D: " . $dir . "/" . $entry;
          }
          else
          {
            $allFiles[] = "F: " . $dir . "/" . $entry;
          }
        }
      }
      closedir($handle);

      natsort($allFiles);

      foreach($allFiles as $value)
      {
        $displayName = substr($value, $rootLen + 4);
        $fileName    = substr($value, 3);
        $linkName    = str_replace(" ", " ", substr($value, $pathLen + 3));


        if (is_dir($fileName))
         {
               echo "<li ><a class='dropdown'><span>" . $displayName . "                    </span></a><ul>";

          myScanDir($fileName, $level + 1, strlen($fileName));
            echo "</ul></li>";
  } 
        else {
      $newstring = substr($displayName, -3);  
      if($newstring == "PDF" || $newstring == "pdf" )

          echo "<li ><a href=\"" . $linkName . "\" style=\"text-decoration:none;\">" . $displayName . "</a></li>";

        }
  $t;
        if($level != 0)
        {
          if($level < $t)
          {
        $r = int($t) - int($level);
        for($i=0;$i<$r;$i++)
        {
            echo "</ul></li>";
        }
          } 
        }
              $t = $level;
      }
          }

        }
        ?>

                                        <li style="color: #ffffff">

                                                <?php                                                   
   //  ListFolder('D:\PDF');
     $root = 'D:\PDF';
   $pathLen = strlen($root);

    myScanDir($root, 0, strlen($root)); 
     ?>


                                        </li>

如果您正在寻找递归目录列出解决方案并将它们排列在多维数组中。 使用以下代码:

<?php
/**
 * Function for recursive directory file list search as an array.
 *
 * @param mixed $dir Main Directory Path.
 *
 * @return array
 */
function listFolderFiles($dir)
{
    $fileInfo     = scandir($dir);
    $allFileLists = [];

    foreach ($fileInfo as $folder) {
        if ($folder !== '.' && $folder !== '..') {
            if (is_dir($dir . DIRECTORY_SEPARATOR . $folder) === true) {
                $allFileLists[$folder] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder);
            } else {
                $allFileLists[$folder] = $folder;
            }
        }
    }

    return $allFileLists;
}//end listFolderFiles()


$dir = listFolderFiles('your searching directory path ex:-F:\xampp\htdocs\abc');
echo '<pre>';
print_r($dir);
echo '</pre>'

?>

这是一个带有scandirarray_filter简单函数来完成这项工作。 使用正则表达式过滤需要的文件。 我删除了. ..和隐藏文件,如.htaccess ,您还可以使用<ul>和颜色自定义输出,并在没有扫描或空目录的情况下自定义错误!。

function getAllContentOfLocation($loc)
{   
    $scandir = scandir($loc);

    $scandir = array_filter($scandir, function($element){

        return !preg_match('/^\./', $element);

    });

    if(empty($scandir)) echo '<li style="color:red">Empty Dir</li>';

    foreach($scandir as $file){

        $baseLink = $loc . DIRECTORY_SEPARATOR . $file;

        echo '<ol>';
        if(is_dir($baseLink))
        {
            echo '<li style="font-weight:bold;color:blue">'.$file.'</li>';
            getAllContentOfLocation($baseLink);

        }else{
            echo '<li>'.$file.'</li>';
        }
        echo '</ol>';
    }
}
//Call function and set location that you want to scan 
getAllContentOfLocation('../app');

我正在寻找与此类似的功能。 我需要目录作为键和子目录作为数组和文件作为值放置。
我使用了以下代码:

/**
 * Return an array of files found within a specified directory.
 * @param  string $dir   A valid directory. If a path, with a file at the end,
 *                       is passed, then the file is trimmed from the directory.
 * @param  string $regex Optional. If passed, all file names will be checked
 *                       against the expression, and only those that match will
 *                       be returned.
 *                       A RegEx can be just a string, where a '/' will be
 *                       prefixed and a '/i' will be suffixed. Alternatively,
 *                       a string could be a valid RegEx string.
 * @return array         An array of all files from that directory. If regex is
 *                       set, then this will be an array of any matching files.
 */
function get_files_in_dir(string $dir, $regex = null)
{
    $dir = is_dir($dir) ? $dir : dirname($dir);
    // A RegEx to check whether a RegEx is a valid RegEx :D
    $pass = preg_match("/^([^\\\\a-z ]).+([^\\\\a-z ])[a-z]*$/i", $regex, $matches);

    // Any non-regex string will be caught here.
    if (isset($regex) && !$pass) {
        //$regex = '/'.addslashes($regex).'/i';
        $regex = "/$regex/i";
    }

    // A valid regex delimiter with different delimiters will be caught here.
    if (!empty($matches) && $matches[1] !== $matches[2]) {
        $regex .= $matches[1] . 'i'; // Append first delimiter and i flag
    }

    try {
        $files = scandir($dir);
    } catch (Exception $ex) {
        $files = ['.', '..'];
    }
    $files = array_slice($files, 2); // Remove '.' and '..'
    $files = array_reduce($files, function($carry, $item) use ($regex) {
        if ((!empty($regex) && preg_match($regex, $item)) || empty($regex)) {
            array_push($carry, $item);
        }

        return $carry;
    }, []);

    return $files;
}

function str_finish($value, $cap)
{
    $quoted = preg_quote($cap, '/');

    return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap;
}

function get_directory_tree($dir)
{
    $fs = get_files_in_dir($dir);
    $files = array();

    foreach ($fs as $k => $f) {
        if (is_dir(str_finish($dir, '/').$f)) {
            $fs[$f] = get_directory_tree(str_finish($dir, '/').$f);
        } else {
            $files[] = $f;
        }
        unset($fs[$k]);

    }

    $fs = array_merge($fs, $files);

    return $fs;
}

有很多东西要考虑。

创建了第一个函数get_files_in_dir函数,以便我可以根据正则表达式获取目录中的所有文件和文件夹。 我在这里使用它是因为它有一些错误检查以确保将目录转换为数组。

接下来,我们有一个简单的函数,它只是在字符串的末尾添加一个正斜杠,如果那里已经没有斜杠了。

最后,我们有get_directory_tree函数,它将遍历所有文件夹和子文件夹并创建一个关联数组,其中文件夹名称是键,文件是值(除非文件夹具有子文件夹)。

先例的答案不符合我的需求。

如果您想要一个平面数组中的所有文件和目录,您可以使用此函数(可在此处找到):

// Does not support flag GLOB_BRACE        
function glob_recursive($pattern, $flags = 0) {
    $files = glob($pattern, $flags);
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
    }
    return $files;
}

就我而言:

$paths = glob_recursive(os_path_join($base_path, $current_directory, "*"));

给我一个这样的数组:

[
'/home/dir',
'/home/dir/image.png',
'/home/dir/subdir',
'/home/dir/subdir/file.php',
]

您还可以使用动态路径生成:

$paths = glob_recursive(os_path_join($base_path, $directory, "*"));

有了这个功能:

function os_path_join(...$parts) {
  return preg_replace('#'.DIRECTORY_SEPARATOR.'+#', DIRECTORY_SEPARATOR, implode(DIRECTORY_SEPARATOR, array_filter($parts)));
}

如果您只获得可以使用的目录:

$paths = glob_recursive(os_path_join($base_path, $current_directory, "*"));
$subdirs = array_filter($paths, function($path) {
    return is_dir($path);
});

你也可以试试这个:

<?php
function listdirs($dir) {
    static $alldirs = array();
    $dirs = glob($dir . '/*', GLOB_ONLYDIR);
    if (count($dirs) > 0) {
        foreach ($dirs as $d) $alldirs[] = $d;
    }
    foreach ($dirs as $dir) listdirs($dir);
    return $alldirs;
}

$directory_list = listdirs('xampp');
print_r($directory_list);
?>
function GetDir($dir) {
    if (is_dir($dir)) {
        if ($kami = opendir($dir)) {
            while ($file = readdir($kami)) {
                if ($file != '.' && $file != '..') {
                    if (is_dir($dir . $file)) {
                        echo $dir . $file;
                        // since it is a directory we recurse it.
                        GetDir($dir . $file . '/');
                    } else {
                        echo $dir . $file;
                    }
                }
            }
        }
        closedir($kami);
    }
}

https://3v4l.org/VsQLb示例在这里

function listdirs($dir) {
    static $alldirs = array();
    $dirs = glob($dir . '/*', GLOB_ONLYDIR);
    if (count($dirs) > 0) {
        foreach ($dirs as $d) $alldirs[] = $d;
    }
    foreach ($dirs as $dir) listdirs($dir);
    return $alldirs;
}
define ('PATH', $_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['PHP_SELF']));
$dir = new DirectoryIterator(PATH);
echo '<ul>';
foreach ($dir as $fileinfo)
{   
    if (!$fileinfo->isDot()) {
       echo '<li><a href="'.$fileinfo->getFilename().'" target="_blank">'.$fileinfo->getFilename().'</a></li>'; 

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

演出迟到了,但要建立在公认的答案之上......

如果您想将所有文件和目录作为数组(可以使用 JavaScript 中的JSON.stringify很好地修饰),您可以将函数修改为:

function listFolderFiles($dir) { 
    $arr = array();
    $ffs = scandir($dir);

    foreach($ffs as $ff) {
        if($ff != '.' && $ff != '..') {
            $arr[$ff] = array();
            if(is_dir($dir.'/'.$ff)) {
                $arr[$ff] = listFolderFiles($dir.'/'.$ff);
            }
        }
    }

    return $arr;
}

对于新手...

要使用上述JSON.stringify ,您的 JS/jQuery 将类似于:

var ajax = $.ajax({
    method: 'POST',
    data: {list_dirs: true}
}).done(function(msg) {
    $('pre').html(
        'FILE LAYOUT<br/>' + 
            JSON.stringify(JSON.parse(msg), null, 4)
    );
});

^ 这是假设您的 HTML 中的某处有一个<pre>元素。 任何风格的 AJAX 都可以,但我认为大多数人都在使用类似于上面的 jQuery 的东西。

以及随附的 PHP:

if(isset($_POST['list_dirs'])) {
    echo json_encode(listFolderFiles($rootPath));
    exit();
}

您之前已经拥有listFolderFiles地方。

就我而言,我已将$rootPath设置为站点的根目录...

$rootPath; 
if(!isset($rootPath)) {
    $rootPath = $_SERVER['DOCUMENT_ROOT'];
}

最终的结果就像...

|    some_file_1487.smthng    []
|    some_file_8752.smthng    []
|    CSS    
|    |    some_file_3615.smthng    []
|    |    some_file_8151.smthng    []
|    |    some_file_7571.smthng    []
|    |    some_file_5641.smthng    []
|    |    some_file_7305.smthng    []
|    |    some_file_9527.smthng    []
|    
|    IMAGES    
|    |    some_file_4515.smthng    []
|    |    some_file_1335.smthng    []
|    |    some_file_1819.smthng    []
|    |    some_file_9188.smthng    []
|    |    some_file_4760.smthng    []
|    |    some_file_7347.smthng    []
|    
|    JSScripts    
|    |    some_file_6449.smthng    []
|    |    some_file_7864.smthng    []
|    |    some_file_3899.smthng    []
|    |    google-code-prettify    
|    |    |    some_file_2090.smthng    []
|    |    |    some_file_5169.smthng    []
|    |    |    some_file_3426.smthng    []
|    |    |    some_file_8208.smthng    []
|    |    |    some_file_7581.smthng    []
|    |    |    some_file_4618.smthng    []
|    |    
|    |    some_file_3883.smthng    []
|    |    some_file_3713.smthng    []

... and so on...

注意:您的看起来不会完全像这样 - 我已经修改了JSON.stringify以显示选项卡(垂直管道)、对齐所有键控值、删除键上的引号以及其他一些内容。 如果我可以上传它或获得足够的兴趣,我将使用链接修改此答案。

这是我的 PHP 7 风格的方便方法:

  /**
     * @param string $directory
     *
     * @return SplFileInfo[]
     */
    private function getAllFiles(string $directory = './'): array
    {
        $result = [];

        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory), RecursiveIteratorIterator::SELF_FIRST );
        /** @var $fileInfo SplFileInfo */
        foreach ($iterator as $fileInfo ) {

            if ($fileInfo->isFile()) {
               $result[] = $fileInfo;
            }
        }

        return $result;
    }

这是另一个作为生成器的递归scandir() 生成器生成完整路径(格式为"basedir/subdirs.../file" ),因此它不太适合树形显示,更适合您想要对文件路径执行其他操作的目录扫描 - 例如显示一个图片库。

function listFolderFiles($dir){
    foreach(scandir($dir) as $file){
        if ($file[0] == '.')
            continue;
        if (is_dir("$dir/$file"))
            foreach (listFolderFiles("$dir/$file") as $infile)
                yield $infile;
        else
            yield "${dir}/${file}";
    }
}

此实现通过跳过所有 UNIX 隐藏文件(以句点开头的文件)来跳过目录指针 - 如果您想获得“隐藏”文件,那么您需要将目录指针跳过方法更改为其他内容。

你可以像这样使用它:

<?php foreach (listFolderFiles('.') as $file) {
    ?>
    <?php echo $file?><br/>
    <?php
}?>

这篇文章是给 Shef(发布正确答案的那个人)的。 这是我想向他展示我对他的代码的欣赏程度以及我对它所做的一切的唯一方式。

<!DOCTYPE html>
<head><title>Displays Folder Contents</title></head>
<?php

function frmtFolder($Entity){
 echo '<li style="font-weight:bold;color:black;list-style-type:none">' . $Entity;
}

function frmtFile($dEntry, $fEntry){
echo '<li style="list-style-type:square">' . '<a href="' . $dEntry . '/' . $fEntry . 
'"> ' . $fEntry . ' </a>';
}

function listFolderFiles($dir) {
$ffs = scandir($dir);

unset($ffs[array_search('.', $ffs, true)]);
unset($ffs[array_search('..', $ffs, true)]);
unset($ffs[array_search('index.html', $ffs, true)]);
// prevent empty ordered elements
if (count($ffs) < 1) {return;}
echo '<ul>';
foreach ($ffs as $ff) {
    if (is_dir($dir . '/' . $ff)) {
     frmtFolder($dir);
    } else {
     frmtFile($dir, $ff);
    }
    if (is_dir($dir . '/' . $ff)) {
        listFolderFiles($dir . '/' . $ff);
    }
    echo '</li>';
}
echo '</ul>';
}
listFolderFiles('Folder_To_List_Here');

我计划在未来扩展 frmtFile 以使用音频和视频标签。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM