
本文详解如何通过 php 安全、规范地扫描目录(如 archives/),筛选特定文件,生成结构化 json 数据,并持久化保存到磁盘(如 archives/events.txt),同时规避常见错误(如未定义变量、路径问题、文件覆盖风险)。
本文详解如何通过 php 安全、规范地扫描目录(如 archives/),筛选特定文件,生成结构化 json 数据,并持久化保存到磁盘(如 archives/events.txt),同时规避常见错误(如未定义变量、路径问题、文件覆盖风险)。
在 Web 开发中,动态读取服务器端目录内容并导出为可被前端消费的结构化数据(如 JSON),是一项常见需求。但直接调用 scandir() 后盲目写入,易引发安全、兼容与逻辑问题。以下为完整、健壮的实现方案。
✅ 正确做法:封装函数 + 严格过滤 + JSON 序列化
原始代码存在多个关键缺陷:
- 前端 JavaScript 中 xhr.send(data) 的 data 未声明,导致 ReferenceError;
- PHP 端未做任何文件类型/命名规则校验,scandir() 返回的 .、.. 及目标文件自身(events.txt)会被误写入;
- 使用 print_r($files1, true) 输出的是人类可读的调试字符串,非标准 JSON,无法被 JS JSON.parse() 安全解析;
- 缺少错误处理与路径安全性校验(如防止目录遍历)。
推荐采用以下改进版 PHP 脚本(json-events.php):
<?php function list_contents($dir, $suffix = '.txt') {
// 1. 解析并验证目录路径
$dir = realpath($dir);
if (!$dir || !is_dir($dir)) {
error_log("Invalid directory: {$dir}");
return;
}
// 2. 扫描目录,排除系统隐藏项和目标输出文件
$files = scandir($dir);
$contents = [];
foreach ($files as $file) {
if (in_array($file, ['.', '..', 'events.txt'], true)) {
continue;
}
$full_path = $dir . '/' . $file;
if (is_file($full_path) && strtolower(substr($file, -strlen($suffix))) === strtolower($suffix)) {
$contents[] = $file;
}
}
// 3. 附加业务规则过滤(示例:仅保留14位长度且以"2"开头的.txt文件)
foreach ($contents as $key => $item) {
if (strlen($item) !== 14 || $item[0] !== '2') {
unset($contents[$key]);
}
}
$contents = array_values($contents); // 重置数组键
// 4. 生成标准 JSON 并安全写入
$json = json_encode($contents, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
if ($json === false) {
error_log('JSON encode failed: ' . json_last_error_msg());
return;
}
$output_file = $dir . '/events.txt';
if (file_put_contents($output_file, $json) === false) {
error_log("Failed to write to {$output_file}");
}
}
// 执行函数
list_contents('archives', '.txt');
?>
? 前端调用建议(修复 xhr.send(data) 错误)
原 JS 中 data 未定义是根本原因。若只需触发 PHP 生成文件,无需传参,应改为:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
function LISTevents() {
const xhr = new XMLHttpRequest();
xhr.open('POST', 'json-events.php');
xhr.onload = function () {
if (xhr.status === 200) {
console.log('Events list generated successfully.');
} else {
console.error('Server error:', xhr.statusText);
}
};
xhr.onerror = function () {
console.error('Network error.');
};
xhr.send(); // ✅ 移除未定义的 `data`
return false;
}
⚠️ 注意事项:
- 权限安全:确保 Web 服务器用户对 archives/ 目录有读写权限,但禁止公开访问 events.txt(可通过 .htaccess 或 Nginx 配置限制);
- 并发风险:高并发场景下,多个请求同时写入同一文件可能导致数据损坏,建议添加文件锁(flock())或改用唯一临时文件 + 原子重命名;
- 扩展性:如需支持子目录递归、大小过滤或时间排序,可基于 RecursiveDirectoryIterator 进一步增强;
- 替代方案:生产环境更推荐使用现代 PHP 框架(如 Laravel 的 Storage)或 CLI 脚本定时生成,而非依赖 HTTP 请求触发。
最终生成的 archives/events.txt 将是标准 JSON 数组,例如:
[ "20240501103000.txt", "20240502141522.txt" ]
前端可直接通过 fetch() 读取并解析,实现可靠的数据同步。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










