fix: 优化文件扫描

This commit is contained in:
邹景立 2024-10-15 14:17:20 +08:00
parent 39e018ad4e
commit c94723315a

View File

@ -21,6 +21,8 @@ namespace think\admin\extend;
use Closure; use Closure;
use FilesystemIterator; use FilesystemIterator;
use Generator; use Generator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo; use SplFileInfo;
/** /**
@ -112,32 +114,31 @@ class ToolsExtend
$files[] = $short ? $info->getBasename() : $info->getPathname(); $files[] = $short ? $info->getBasename() : $info->getPathname();
} }
} elseif ($info->isDir()) { } elseif ($info->isDir()) {
foreach (static::findFilesYield($info->getPathname(), $filterFile, $filterPath, $depth) as $file) { foreach (static::findFilesYield($info->getRealPath(), $filterFile, $filterPath, $depth) as $file) {
$files[] = $short ? substr($file->getRealPath(), strlen($info->getPathname()) + 1) : $file->getRealPath(); $files[] = $short ? substr($file->getRealPath(), strlen($info->getRealPath()) + 1) : $file->getRealPath();
} }
} }
return $files; return $files;
} }
/** /**
* 递归扫描指定目录,返回文件或目录的 SplFileInfo 对象。 * 递归方式扫描指定目录,返回文件或目录的 SplFileInfo 对象。
* @param string $path 目录路径。 * @param string $path 目录路径。
* @param \Closure|null $filterFile 文件过滤器闭包,返回 true 表示文件被接受。 * @param \Closure|null $filterFile 文件过滤器闭包,返回 true 表示文件被接受。
* @param \Closure|null $filterPath 目录过滤器闭包,返回 true 表示目录被接受。 * @param \Closure|null $filterPath 目录过滤器闭包,返回 true 表示目录被接受。
* @param ?integer $depth 当前递归深度null 表示无限制深度 * @param ?integer $depth 当前深度限制null 表示无限制深度
* @param boolean $appendPath 是否包含目录本身在结果中。 * @param boolean $apath 是否包含目录本身在结果中。
* @return \Generator 返回 SplFileInfo 对象的生成器。 * @return \Generator 返回 SplFileInfo 对象的生成器。
*/ */
private static function findFilesYield(string $path, ?Closure $filterFile = null, ?Closure $filterPath = null, ?int $depth = null, bool $appendPath = false): Generator private static function findFilesYield(string $path, ?Closure $filterFile = null, ?Closure $filterPath = null, ?int $depth = null, bool $apath = false): Generator
{ {
if (file_exists($path)) { if (file_exists($path)) {
foreach (is_file($path) ? [new SplFileInfo($path)] : new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS) as $item) { $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
if (($isDir = $item->isDir() && !$item->isLink()) && ($filterPath === null || $filterPath($item))) { foreach ($iterator as $item) {
if ($depth === null || $depth > 1) { if (is_numeric($depth) && $iterator->getDepth() >= $depth) continue;
yield from static::findFilesYield($item->getPathname(), $filterFile, $filterPath, $depth !== null ? $depth - 1 : null, $appendPath); if ($item->isDir() && !$item->isLink()) {
} ($filterPath === null || $filterPath($item)) && $apath && yield $item;
if ($appendPath) yield $item; } elseif ($filterFile === null || $filterFile($item)) {
} elseif (!$isDir && ($filterFile === null || $filterFile($item))) {
yield $item; yield $item;
} }
} }