想要获取一个目录下的全部文件,一般都是利用递归函数
例如:
function readFile($path, &$res)
{
$content = scandir($path);
foreach ($content as $v) {
if ($v == '.' || $v == '..') continue;
if (is_dir($path . '/' . $v)) {
readFile($path . '/' . $v, $res);
} else {
$res[] = $path . '/' . $v;
}
}
}
/**
* 获取route目录下的所有路由文件,返回所有路由组成的数组
*/
$path = __DIR__ . '/../../route';
$result_path = array();
readFileOne($path, $result_path);
$result = [];
foreach ($result_path as $v) {
$result = array_merge($result, (include($v . '')) ?: []);
}
return $result;
但是如果$path
目录下的文件或者文件夹非常多,$content
和$res
两个变量可能会导致内存溢出。
$content
变量溢出问题,可以利用opendir、readdir、closedir等函数逐步取出$path
目录下的内容
function readFile($path, &$res)
{
$open = opendir($path);
while (($v = readdir($open)) !== false) {
if ('.' == $v || '..' == $v) {
continue;
}
if (is_file($path . '/' . $v)) {
$res[] = $path . '/' . $v;
continue;
}
readFile($path . '/' . $v, $res);
}
closedir($open);
}
$res
变量溢出问题,可以利用yield语法生成器
function readFile($path, &$res)
{
$open = opendir($path);
while (($v = readdir($open)) !== false) {
if ('.' == $v || '..' == $v) {
continue;
}
if (is_file($path . '/' . $v)) {
yield $path . '/' . $v;
continue;
}
readFile($path . '/' . $v,$res);
}
closedir($open);
}
运行会发现并不能实现,查找资料后发现递归中需要用到语法yield from
(才知道还有这种 O(∩_∩)O)
/**
* 获取目录里的文件
* @param string $path
* @return Generator
*/
function getFile(string $path)
{
$open = opendir($path);
while (($v = readdir($open)) !== false) {
if ('.' == $v || '..' == $v) {
continue;
}
if (is_file($path . '/' . $v)) {
yield $path . '/' . $v;
continue;
}
yield from getFile($path . '/' . $v);
}
closedir($open);
}
注意:若把函数is_file改成is_dir,则会连目录一并取出(而不是只取出文件)