当前位置: 首页> 最新文章列表> 使用 md5_file() 生成本地文件签名数据库

使用 md5_file() 生成本地文件签名数据库

M66 2025-05-31

在管理大量本地文件(如软件分发包、文档、媒体资源等)时,确保文件完整性是非常关键的一个环节。一个有效的方式就是为每个文件生成其 MD5 签名,并将其存储在一个数据库中,以便后续进行校验和变更检测。PHP 提供了一个非常方便的函数 —— md5_file(),它可以直接返回文件的 MD5 校验和。

本文将介绍如何使用 md5_file() 为本地文件生成签名,并构建一个完整的文件校验数据库。

一、准备工作

在开始之前,请确保你的服务器或开发环境中安装了 PHP,并且具有文件系统访问权限。我们将以一个简单的 PHP 脚本为例,递归扫描某个目录中的所有文件,生成它们的 MD5 签名并将其保存至数据库中。

二、示例代码

以下是一个完整的示例脚本,使用 PDO 写入 SQLite 数据库。你也可以根据需要替换为 MySQL、PostgreSQL 等数据库。

<?php
$directory = __DIR__ . '/files';
$dbFile = __DIR__ . '/checksum.db';

$pdo = new PDO('sqlite:' . $dbFile);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// 初始化数据库
$pdo->exec("CREATE TABLE IF NOT EXISTS file_checksums (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    path TEXT UNIQUE,
    md5 TEXT,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)");

// 扫描目录并处理文件
function scanFiles($dir, $pdo) {
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
    foreach ($files as $file) {
        if ($file->isFile()) {
            $path = $file->getRealPath();
            $md5 = md5_file($path);

            $stmt = $pdo->prepare("INSERT INTO file_checksums (path, md5)
                VALUES (:path, :md5)
                ON CONFLICT(path) DO UPDATE SET md5 = :md5, updated_at = CURRENT_TIMESTAMP");
            $stmt->execute([
                ':path' => $path,
                ':md5' => $md5,
            ]);
            echo "已处理:$path\n";
        }
    }
}

scanFiles($directory, $pdo);
echo "文件签名生成完成。\n";

三、校验文件完整性

之后你可以再运行一次该脚本,它会自动更新数据库中已存在的文件记录。你也可以创建一个独立的校验脚本,对比当前文件的 MD5 与数据库中记录的 MD5 值是否一致:

<?php
$directory = __DIR__ . '/files';
$dbFile = __DIR__ . '/checksum.db';

$pdo = new PDO('sqlite:' . $dbFile);

$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
foreach ($files as $file) {
    if ($file->isFile()) {
        $path = $file->getRealPath();
        $currentMd5 = md5_file($path);

        $stmt = $pdo->prepare("SELECT md5 FROM file_checksums WHERE path = :path");
        $stmt->execute([':path' => $path]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($row) {
            if ($row['md5'] !== $currentMd5) {
                echo "文件已被修改:$path\n";
            }
        } else {
            echo "新文件:$path\n";
        }
    }
}

四、实用建议

  1. 权限控制:确保文件和数据库的读写权限正确配置。

  2. 定期运行:可以通过 cron 定时任务定期运行签名更新或校验脚本。

  3. 远程验证:如果你需要远程验证文件完整性,可以将生成的签名通过接口上传到服务器(如 <code>https://m66.net/api/upload_md5</code>)。

五、结语

通过 md5_file() 和数据库存储结合,你可以轻松构建一套高效且稳定的文件完整性校验机制。这种方法适用于本地文件监控、系统安全审计、部署自动化等场景,有效提高了系统的可靠性和可追溯性。