PHP目录遍历函数需在调用前/后明确注释遍历目的、过滤逻辑与安全边界:scandir()须注明“已排除父目录和当前目录”,RecursiveDirectoryIterator需强调“必须包装为RecursiveIteratorIterator”,路径拼接要标明版本兼容性,用户输入校验注释须紧贴$dir合法性检查,PHPDoc应规范@param和@return类型,禁用功能时用[DISABLED IN PROD]等明确标识。
直接在 scandir()、opendir() + readdir() 或 RecursiveDirectoryIterator 调用前/后加注释,核心是说明「遍历目的」「过滤逻辑」「安全边界」。不写清楚容易被当成漏洞入口。
scandir() 返回数组,需手动 array_filter() 排除 '.' 和 '..' —— 注释里必须点明“已排除父目录和当前目录”RecursiveDirectoryIterator 时,若没套 RecursiveIteratorIterator,会报 Fatal error: Uncaught UnexpectedValueException —— 注释建议写成:// 必须包装为 RecursiveIteratorIterator 才能 foreach 遍历
dirname(__FILE__) . '/uploads' 比 __DIR__ . '/uploads' 更老但兼容 PHP 5.2+;后者更简洁,但注释里得写清最低版本要求关键不是“有没有注释”,而是注释是否紧贴输入校验逻辑。用户传进来的 $dir 变量,必须在进入遍历前完成合法性检查,注释就该落在那里。
/**
* 检查 $dir 是否为 uploads 子目录,禁止 ../ 穿越
* 允许路径:'images', 'pdfs';拒绝:'../config', '/etc/passwd'
*/
$dir = basename($_GET['path'] ?? '');
if (!in_array($dir, ['images', 'pdfs'], true)) {
die('Invalid directory');
}
// 此处开始遍历:$realPath = __DIR__ . '/uploads/' . $dir;
realpath($user_input),注释必须写明:// realpath() 同时解决 ../ 和符号链接问题,但返回 false 表示非法路径
想让 PhpStorm 或 VS Code 的 intelephense 显示目录结构提示,得在函数文档块里用 @return 和 @param 标准化描述,而不是写“遍历文件夹”这种废话。
/** * 获取指定目录下所有 .log 文件(不含子目录) * @param string $path 绝对路径,已通过 validateUploadDir() 校验 * @return array键为文件名,值为完整路径 */ function listLogFiles(string $path): array { $files = scandir($path); return array_filter($files, fn($f) => pathinfo($f, PATHINFO_EXTENSION) === 'log'); }
@param 必须注明路径是否已校验、是否为绝对路径——很多 bug 来自“以为参数干净,其实没过滤”array 比 array 强,IDE 能据此推导 foreach 中的 $filename 和 $fullPath 类型
上线前关掉调试用的遍历页面,不能只删代码或加 exit,得用注释锁定意图,否则下次改需求可能误开。
// [DISABLED IN PROD] 目录浏览接口,仅用于本地开发验证,禁止恢复
// 仅限 192.168.1.0/24 内网访问,外网请求直接 403
define('ALLOW_DIR_LISTING', false); 控制开关时,注释必须同步更新:// 修改此常量需同步更新 nginx 配置 deny all;
最常被忽略的是日志记录——即使功能关闭,也要在注释里留一句:// 若需临时启用,请同时打开 access_log 并设置 rotate 策略,防止日志爆炸