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');
使用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/zh/class.recursivetreeiterator.php
通过使用RecursiveTreeIterator::setPrefixPart
来更改前缀,例如$it->setPrefixPart(RecursiveTreeIterator::PREFIX_LEFT, "|");
,还可以控制树的ASCII表示。
这段代码以树形图的方式列出所有目录和文件,并按字母顺序排序。它是一个具有所有站点资源超链接的网站地图生成器。完整的网页源代码在此处。您需要更改倒数第九行上的路径。
<?php
$pathLen = 0;
function prePad($level)
{
$ss = "";
for ($ii = 0; $ii < $level; $ii++)
{
$ss = $ss . "| ";
}
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
以下函数是对@Shef的回答进行重新实现,并使用了directoryIterator
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');
之前的答案没有满足我的需求。
如果你想要一个包含所有文件和目录的扁平数组,可以使用这个函数(在这里找到):
// 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 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>'
?>
我正在寻找类似的功能。我需要将目录作为键,子目录作为数组,文件只需放置为值。
我使用了以下代码:
/**
* 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
函数将遍历所有文件夹和子文件夹,并创建一个关联数组,其中文件夹名称是键,文件是值(除非该文件夹有子文件夹)。
scandir
和 array_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');
$pathLen = 0;
function prePad($level)
{
$ss = "";
for ($ii = 0; $ii < $level; $ii++)
{
$ss = $ss . "| ";
}
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>
exec
并非在所有地方都被允许使用,因此您可能会遇到运行问题。 - Shef$ff
在foreach
循环中保存文件名。使用相应的函数,如filesize($ff)
、filemtime($ff)
、filetype($ff)
等,就可以实现你想要的功能。 - Shef