/**
* 批量获取某目录及子孙目录下的所有图片image、视频video、目录dir、目录树dir_tree
* @param array $filter_array 要过滤的目录名称列表
*/
function get_file_list($type, $path, $filter_array=array()){
if(!in_array($type, explode(',','image,video,dir,dir_tree')))return return_data(1,'类型错误:'.$type);
/**
* SELF_FIRST 目录从浅到深返回
* CHILD_FIRST 先处理子节点,目录从深到浅返回
*/
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
$photos = [];
$videos = [];
$dirs = [];
foreach ($iterator as $SplFileInfo){
$skip=false;
foreach($filter_array as $filter){
if(strpos($SplFileInfo->getRealPath(), $filter)!==false){
$skip=true;
break;
}
}
if($skip)continue;
/*
$SplFileInfo 实际是 RecursiveDirectoryIterator 类
参考:https://www.php.net/manual/zh/class.recursivedirectoryiterator.php
常用方法:
getExtension 获取扩展名,如:jpg
getFilename 获取文件名,如:abc.jpg
getPathname 返回创建 SplFileInfo 对象时传入的原始路径字符串(不做任何解析或验证),如:D:\web/pictures\2001\a.jpg
getRealPath 返回文件的规范化的绝对路径,如:D:\web\pictures\2001\a.jpg
getSize
getType
isDir
isFile
isLink 快捷方式,会自动跟随与链接文件
*/
if($SplFileInfo->isDir()){
$dirs[$iterator->getDepth()][] = $SplFileInfo->getRealPath();
}else if($SplFileInfo->isFile()){
$cur_path = dirname($SplFileInfo->getRealPath());
$cur_file = $SplFileInfo->getRealPath();
$cur_size = $SplFileInfo->getSize();
switch(strtolower($SplFileInfo->getExtension())){
case 'jpe':
case 'jpg':
case 'jpeg':
case 'png':
//因生成缩略图时可能出错,所以不展示大图片
if($cur_size < 20*1024*1024){
$photos[$cur_path][] = $cur_file;
}
break;
case 'mp4':
$videos[$cur_path][] = $cur_file;
break;
}
/*
$photos[] = [
'getRealPath' => $SplFileInfo->getRealPath(),
'getPathname' => $SplFileInfo->getPathname(),
'getExtension' => $SplFileInfo->getExtension(),
'getFilename' => $SplFileInfo->getFilename(),
'getSize' => $SplFileInfo->getSize(),
'getType' => $SplFileInfo->getType(),
];
*/
}
}
ksort($dirs);
// 构建树形结构
$dir_tree = [];
foreach ($dirs as $depth => $paths) {
foreach ($paths as $path) {
insertPathIntoTree($dir_tree, $path, $path);
}
}
switch($type){
case 'image':
return return_data(0,'',$photos);
case 'video':
return return_data(0,'',videos);
case 'dir':
return return_data(0,'',dir);
case 'dir_tree':
return return_data(0,'',dir_tree);
}
}
//生成目录树
function insertPathIntoTree(&$tree, $currentPath, $rootPath) {
// 计算相对路径
$relativePath = substr($currentPath, strlen($rootPath));
if (empty($relativePath)) {
$tree[$currentPath] = [];
return;
}
// 分割路径
$parts = explode(DIRECTORY_SEPARATOR, trim($relativePath, DIRECTORY_SEPARATOR));
// 找到父路径
$parentPath = $rootPath;
for ($i = 0; $i < count($parts) - 1; $i++) {
$parentPath .= DIRECTORY_SEPARATOR . $parts[$i];
}
// 如果是根目录下的直接子目录
if ($parentPath === $rootPath) {
$tree[$currentPath] = [];
return;
}
// 在树中找到父路径对应的节点
$current = &$tree;
$pathSoFar = $rootPath;
for ($i = 0; $i < count($parts) - 1; $i++) {
$pathSoFar .= DIRECTORY_SEPARATOR . $parts[$i];
// 查找当前路径在树中的位置
$found = false;
foreach ($current as $key => $value) {
if (strpos($key, $pathSoFar) === 0) {
$current = &$current[$key];
$found = true;
break;
}
}
if (!$found) break;
}
// 在父节点中添加当前路径
$current[$currentPath] = [];
}