PHP获取同目录相邻文件的代码优化方案咨询
同目录相邻文件查询实现优化
原代码可以大幅简化,同时修复现有逻辑的潜在问题:
原代码存在的问题
- 冗余遍历:定位到当前文件索引后,额外两次循环遍历全量文件数组找上/下文件,存在无意义的性能消耗
- 逻辑漏洞:
$rcount > 2的判断条件错误,目录下有2个文件时本应能取到相邻项,会被直接跳过;没有处理首尾文件的下标越界问题;声明了完全未使用的变量$i - 安全隐患:SQL语句直接拼接传入变量,存在SQL注入风险
- 结果不实用:直接拼接两个文件名字符串,无法区分哪个是上一个、哪个是下一个
- 效率偏低:找到目标文件后没有终止循环,会继续遍历剩余无意义的数组项
优化后的基础版(兼容原逻辑,适合目录文件量不大的场景)
核心思路是把结果集转为连续数字索引数组后,直接通过下标取相邻元素,删除所有冗余循环:
$title = $file->name; // 当前文件名 $in_dir = $file->indir; // 当前目录ID // 生产环境建议把SQL改成预处理写法,避免注入风险,参考示例: // $stmt = $db->prepare("SELECT * FROM `". MAI_PREFIX ."files` WHERE `indir` = ?"); // $stmt->execute([$in_dir]); // $r_file = $stmt->fetchAll(); $r_file = $db->select("SELECT * FROM `". MAI_PREFIX ."files` WHERE `indir`='$in_dir'"); $fileCount = count($r_file); $related = [ 'prev' => null, // 存储上一个文件对象 'next' => null // 存储下一个文件对象 ]; if ($fileCount >= 2) { // 转为连续数字索引数组,避免原数组键不连续导致的下标取值错误 $fileList = array_values($r_file); $listLength = count($fileList); foreach ($fileList as $index => $item) { if ($item->name === $title) { // 非首项时取上一个元素 if ($index > 0) { $related['prev'] = $fileList[$index - 1]; } // 非末项时取下一个元素 if ($index < $listLength - 1) { $related['next'] = $fileList[$index + 1]; } break; // 匹配到目标后直接退出循环,减少无用遍历 } } } // 调用示例 // $prevName = $related['prev']?->name; // $nextName = $related['next']?->name;
进阶版(适合单目录文件量较大的场景)
如果单个目录下文件数量较多(比如数百上千个),不建议每次查询全量文件列表,可以直接通过SQL定位相邻文件,仅需查询2条记录,性能不受目录文件总数影响:
// 注意:如果业务是按文件上传时间/自增ID排序,把ORDER BY后的字段替换为对应业务字段即可 // 查询上一个相邻文件 $prevStmt = $db->prepare("SELECT * FROM `". MAI_PREFIX ."files` WHERE `indir` = ? AND `name` < ? ORDER BY `name` DESC LIMIT 1"); $prevStmt->execute([$in_dir, $title]); $related['prev'] = $prevStmt->fetch(); // 查询下一个相邻文件 $nextStmt = $db->prepare("SELECT * FROM `". MAI_PREFIX ."files` WHERE `indir` = ? AND `name` > ? ORDER BY `name` ASC LIMIT 1"); $nextStmt->execute([$in_dir, $title]); $related['next'] = $nextStmt->fetch();
这种写法完全不需要在PHP层遍历文件列表,大流量场景下性能提升非常明显。
内容的提问来源于stack exchange,提问作者Same Anime
相关产品推荐
相关产品推荐

