如何使用 PHP 枚举目录文件并以 JSON 格式保存到磁盘

作者:袖梨 2026-07-01

本文详解如何在 php 中安全、精准地扫描指定目录(如 archives/),筛选符合命名规范的文件,并将结果以 json 格式写入磁盘(如 archives/events.txt),同时规避常见错误(如未定义变量、路径问题、冗余文件写入等)。

本文详解如何在 php 中安全、精准地扫描指定目录(如 archives/),筛选符合命名规范的文件,并将结果以 json 格式写入磁盘(如 archives/events.txt),同时规避常见错误(如未定义变量、路径问题、冗余文件写入等)。

在 Web 开发中,常需动态获取服务器端文件列表并持久化存储(例如生成事件索引、缓存文件清单)。但直接调用 scandir() 并写入文件时,易出现路径解析错误、文件覆盖风险、格式不兼容或前端 AJAX 调用失败等问题。以下提供一套健壮、可复用的解决方案。

✅ 正确做法:服务端 PHP 处理逻辑

首先,避免硬编码路径与不安全筛选。原始代码中 scandir('archives') 未校验目录存在性,且 print_r($files1, true) 生成的是人类可读的调试字符串,而非标准 JSON,不利于后续 JavaScript 解析。改进后的函数具备路径验证、后缀过滤、格式标准化和防自写入能力:

<?phpfunction 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) {        $full_path = $dir . '/' . $file;        // 排除目录项、隐藏文件及即将写入的目标文件        if ($file === '.' || $file === '..' || $file === 'events.txt' || !is_file($full_path)) {            continue;        }        // 按后缀过滤(如仅 .txt 文件)        if (strtolower(substr($file, -strlen($suffix))) === strtolower($suffix)) {            $contents[] = $file;        }    }    // 3. 高级筛选(示例:仅保留 14 位长度且以 '2' 开头的文件名,如 '20240501-event.txt')    $filtered = [];    foreach ($contents as $file) {        if (strlen($file) === 14 && strpos($file, '2') === 0) {            $filtered[] = $file;        }    }    // 4. 以标准 JSON 格式写入磁盘(非 print_r)    $json_data = json_encode($filtered, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);    $output_file = $dir . '/events.txt';    if (file_put_contents($output_file, $json_data) === false) {        error_log("Failed to write to {$output_file}");        return false;    }    return true;}// 执行扫描并保存list_contents('archives', '.txt');?>

⚠️ 前端调用注意事项(修复 data is not defined 错误)

原始 JS 中 xhr.send(data) 报错,因 data 变量未声明。若无需传参,应调用 xhr.send()(空括号);若需 POST 数据,须显式构造:

function LISTevents() {    const xhr = new XMLHttpRequest();    xhr.open("POST", "json-events.php");    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");    xhr.onload = function() {        if (xhr.status === 200) {            console.log("File list saved successfully:", xhr.response);        } else {            console.error("Server error:", xhr.statusText);        }    };    xhr.onerror = () => console.error("Network error");    xhr.send(); // ✅ 无参数时不要传 data    return false;}

? 关键要点总结

  • 路径安全:始终使用 realpath() 验证目录真实性,防止路径遍历攻击;
  • 输出格式:用 json_encode() 替代 print_r(),确保前端可直接 JSON.parse();
  • 防自污染:显式排除 events.txt,避免扫描结果包含自身导致无限循环或数据异常;
  • 容错处理:添加 is_readable()、file_put_contents() 返回值判断,便于定位写入失败原因;
  • 扩展友好:函数支持自定义后缀与目录,易于适配其他场景(如 list_contents('uploads', '.pdf'))。

执行该脚本后,archives/events.txt 将生成标准 JSON 数组(如 ["20240501-log.txt","20240502-data.txt"]),可被前端可靠消费,彻底解决“文件未创建”与“格式不可用”两大痛点。

立即学习“PHP免费学习笔记(深入)”;

相关文章

精彩推荐