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

Please give me a solution for listing all the folders,subfolders,files in a directory using php. My folder structure is like this:

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

I want to get the list of all the files inside each folder.

Is there any shell script command in php?

177266 次浏览

我真的很喜欢 SPL 库,他们提供迭代器,包括 递归目录迭代器

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
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);
?>
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>';

此代码在树视图中按排序顺序列出所有目录和文件。这是一个站点地图生成器,包含所有站点资源的超链接。完整的网页资源在这里。你需要从最后改变第九行的路径。

<?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>

如果您想使用 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');

显示文件夹结构的一种非常简单的方法是使用 RecursiveTreeIterator类(PHP5 > = 5.3.0,PHP7)并生成一个 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(例如 $it->setPrefixPart(RecursiveTreeIterator::PREFIX_LEFT, "|");)更改前缀来控制树的 ASCII 表示形式

节目迟到了,但是为了建立在 接受的答案的基础上..。

If you want to have all the files and directories in as array (that can be prettied-up nicely with JSON.stringify in javascript), you can modify the function to:

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

^ This is assuming you have a <pre> element in your HTML somewhere. Any flavour of AJAX will do, but I figure most people are using something similar to the jQuery above.

以及相应的 PHP:

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

之前已经有 listFolderFiles的地方。

In my case, I've set my $rootPath to the root directory of the site...

$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来显示标签(垂直管道) ,对齐所有键值,删除关键字的引号,以及其他一些东西。我会修改这个答案与一个链接,如果我曾经得到上传它,或得到足够的兴趣。

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

$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>
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);
}
}

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

<?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执行 job. filter needed files using regex. I removed . .. and hidden files like .htaccess, you can also customise output using <ul> and colors and also customise errors in case no scan or empty dirs!.

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函数,它将遍历所有文件夹和子文件夹,并创建一个关联数组,其中文件夹名称是键,文件是值(除非文件夹有子文件夹)。

这篇文章是为 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 以使用音频和视频标记。

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

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

// 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);
});

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;
}

这是我的方便方法 PHP7风格:

  /**
* @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;
}

Here's another recursive scandir() as a generator. The generator yields full paths (in the form "basedir/subdirs.../file") so it is less suitable for a tree display and more appropriate for directory scanning where you want to do something else with the file paths - such as display an image gallery.

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
}?>