以下脚本用于搜索指定路径中的文档/文件。它工作得很好,只是当一个子文件夹有一个子文件夹时,它会将其列为一个文件/使其可单击。这不是我想要的。我希望脚本只显示每个文件夹中的文件(包括子目录中的文件)。我希望我的解释不会太混乱,哈哈。
由于我无法发布截图,我将尝试解释。
当前文件夹结构:
vbfiles/
-dir1/
-subdir1/
-filesubdir1.doc
-subdir2/
-filesubdir2.doc
-dir1file1.doc
-dir1file2.doc
-dir1file3.doc
-dir2/
-subdir3/
-filesubdir3.doc
-subdir4/
-filesubdir4.doc
-dir2file4.doc
-dir2file5.doc
-dir2file6.doc
结果(我要删除的标记为"<--NO"的内容:):
Found 14 file(s)
dir1
dir1file3.doc
dir1file2.doc
subdir1 <-- NO
subdir2 <-- NO
dir1file1.doc
subdir1
filesubdir1.doc
subdir2
filesubdir2.doc
dir2
subdir3 <-- NO
dir2file4.doc
dir2file5.doc
subdir4 <-- NO
dir2file6.doc
subdir3
filesubdir3.doc
subdir4
filesubdir4.doc
代码:
<?php
define("PATH_ROOT", dirname(__FILE__) . "/");
define("PATH_FILES", PATH_ROOT . "vbfiles/");
function files($dir) {
$files = array();
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$files[] = "$entryn";
}
}
closedir($handle);
}
return $files;
}
function getdirname($name) {
$name = substr($name, 0, -1);
$x = explode("/", $name);
return end($x);
}
function read_all_files($root = '.') {
$files = array('files' => array(), 'dirs' => array());
$directories = array();
$last_letter = $root[strlen($root) - 1];
$root = ($last_letter == '\' || $last_letter == '/') ? $root : $root . DIRECTORY_SEPARATOR;
$directories[] = $root;
while (sizeof($directories)) {
$dir = array_pop($directories);
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file == '.' || $file == '..') {
continue;
}
$file = $dir . $file;
if (is_dir($file)) {
$directory_path = $file . DIRECTORY_SEPARATOR;
array_push($directories, $directory_path);
$files['dirs'][] = $directory_path;
} elseif (is_file($file)) {
$files['files'][] = $file;
}
}
closedir($handle);
}
}
return $files;
}
$searchstr = $_GET['search'];
$type = "files";
if ($type == "files") {
$folders = read_all_files(PATH_FILES);
$found = array();
$count = 0;
sort($folders['files']);
sort($folders['dirs']);
foreach ($folders['dirs'] as $folder) {
foreach (files($folder) as $filename) {
$m = preg_match("#$searchstr#si", $filename, $ids);
if ($m) {
$found[getdirname($folder)][] = $filename;
$count++;
}
}
}
$dir = "vbfiles/";
if (count($found)) {
echo "<h3>Found " . $count . " file(s)</h3>";
foreach ($found as $folder => $files) {
echo "<ul id='navi_lvl0'>
<li class='folder'>" . $folder . "</li>
<ul id='navi_lvl1'>";
foreach ($files as $file) {
echo "<li class='document'><a href='$dir$folder/$file' target='_blank'>" . $file . "</a></li>";
}
echo "</ul></ul>";
}
} else {
echo "No files found";
}
}
?>
此函数列出目录中的文件。它还接近嵌套的子目录。当我需要同样的功能时,我写了这个。
/**
* Return files of desired extension from a directory
*
* @author Pankaj Garg <garg.pankaj15@gmail.com>
*
* @param string $_dirPath path to directory
* @param string $_extension desired file extension
* @param int $_before files to get before this time (in seconds)
* @param int $_limit no of files
*
* @return array $_scannedFiles array of files
*/
function ScanFilesFromDirectory($_dirPath, $_extension, $_before = 0, $_limit = 10)
{
$_scannedFiles = array();
if (empty($_extension)) {
return $_scannedFiles;
}
if (!is_dir($_dirPath)) {
return $_scannedFiles;
}
//If extension starting with '.', then remove it
$_extension = (stripos($_extension, '.') === 0) ? substr($_extension, 1) : $_extension;
$_handler = opendir($_dirPath);
while ($_fileName = readdir($_handler)) {
//for files starting with '.'
if (stripos($_fileName, '.') === 0) {
continue;
}
if (is_dir($_dirPath . DIRECTORY_SEPARATOR . $_fileName)) {
$_scannedFiles = array_merge($_scannedFiles, ScanFilesFromDirectory($_dirPath . DIRECTORY_SEPARATOR . $_fileName, $_extension, $_before, $_limit));
} else if (is_file($_dirPath . DIRECTORY_SEPARATOR . $_fileName)) {
if (preg_match('/' . preg_quote($_extension) . '$/', $_fileName)) {
if (($_before != 0 && time() - filemtime($_dirPath . DIRECTORY_SEPARATOR . $_fileName)) < $_before) {
continue;
}
$_scannedFiles[] = substr($_fileName, 0, -strlen($_extension) - 1);
}
}
if (count($_scannedFiles) >= $_limit) {
break;
}
}
closedir($_handler);
return $_scannedFiles;
}