
本文详解如何在 php 中安全、规范地扫描目录(如 archives/),筛选特定文件,生成结构化 json 数据,并写入指定文件(如 archives/events.txt),同时规避前端 ajax 调用中常见的变量未定义错误。
本文详解如何在 php 中安全、规范地扫描目录(如 archives/),筛选特定文件,生成结构化 json 数据,并写入指定文件(如 archives/events.txt),同时规避前端 ajax 调用中常见的变量未定义错误。
在 Web 开发中,动态列出服务器端目录内容并持久化存储是一项常见需求,例如归档系统需定期生成事件文件清单。但直接调用 scandir() 并粗暴写入易引发安全与逻辑问题:未校验目录权限、未过滤隐藏文件、未处理路径安全性,且前端 XMLHttpRequest 中误用未声明变量 data(导致 Uncaught ReferenceError)更会中断流程。
以下是一个健壮、可复用的 PHP 解决方案:
✅ 正确实现:安全扫描 + 精准过滤 + JSON 持久化
<?php
function list_contents($dir, $suffix = '.txt') {
// 1. 规范化路径并校验合法性
$dir = realpath($dir);
if (!$dir || !is_dir($dir) || !is_readable($dir)) {
error_log("Invalid or unreadable directory: {$dir}");
return false;
}
// 2. 扫描目录,排除 . 和 .. 等系统条目
$files = scandir($dir);
$contents = [];
foreach ($files as $file) {
$path = $dir . '/' . $file;
// 仅处理普通文件,跳过目录、隐藏文件及目标输出文件本身
if (is_file($path)
&& $file !== 'events.txt'
&& $file !== '.'
&& $file !== '..'
&& str_ends_with($file, $suffix)) {
// 3. 额外业务规则:仅保留 14 字符长度且以 '2' 开头的文件名(如 20240501_event.txt)
if (strlen($file) === 14 && str_starts_with($file, '2')) {
$contents[] = $file;
}
}
}
// 4. 序列化为标准 JSON(非 print_r),写入目标文件
$json = json_encode($contents, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
$output_path = $dir . '/events.txt';
if (file_put_contents($output_path, $json) === false) {
error_log("Failed to write to {$output_path}");
return false;
}
return true;
}
// 调用示例
if (list_contents('archives', '.txt')) {
echo "✅ File list successfully saved to archives/events.txt";
} else {
http_response_code(500);
echo "❌ Failed to generate file list.";
}
?>⚠️ 关键注意事项
- 前端修复:原 JS 中 xhr.send(data) 的 data 未定义——若无需传参,应改为 xhr.send();若需 POST 数据,须先声明 const data = new FormData(); 或 JSON.stringify({...}) 并设置 Content-Type。
- 安全性:realpath() 防止路径遍历攻击;is_readable() 和 is_file() 避免权限错误;显式排除 .、.. 和输出文件自身,防止无限递归或覆盖。
- 兼容性:str_starts_with() 和 str_ends_with() 在 PHP 8.0+ 原生支持;若使用旧版本,请替换为 substr($s, 0, 1) === '2' 和 substr($s, -strlen($suffix)) === $suffix。
- 可维护性:业务规则(如长度、前缀)已解耦为独立条件,便于后续调整;JSON 输出支持 UTF-8 和格式化,利于调试与前端消费。
执行该脚本后,archives/events.txt 将生成标准 JSON 数组,例如:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
[
"20240501_log.txt",
"20240502_report.txt"
]既满足存储需求,又为前端 fetch() 或 XMLHttpRequest 提供了可直接解析的结构化数据源。
立即学习“PHP免费学习笔记(深入)”;


















