在日常网站开发与运维中,文件的完整性是系统安全的重要组成部分。一旦有文件被篡改,可能意味着系统遭受攻击或者数据泄露。为了应对这种情况,我们可以用PHP内置的 md5_file() 函数构建一个简单而实用的文件完整性检测工具。
md5_file() 是PHP提供的一个函数,用于直接计算指定文件的MD5哈希值。其基本语法如下:
md5_file(string $filename, bool $binary = false): string|false
$filename:要计算的文件路径。
$binary:是否以原始二进制格式返回哈希(默认为 false,返回32位的十六进制字符串)。
示例:
$hash = md5_file('example.txt');
echo $hash;
我们将工具设计成两个阶段:
生成基准校验码(基线):记录所有待监测文件的MD5值,并保存到一个JSON文件中。
定期检测:重新计算当前文件的MD5值,与基线文件对比,判断是否被修改、删除或新增。
function generateBaseline($dir, $baselineFile = 'baseline.json') {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
$hashes = [];
foreach ($files as $file) {
if ($file->isFile()) {
$path = str_replace('\\', '/', $file->getRealPath());
$hashes[$path] = md5_file($path);
}
}
file_put_contents($baselineFile, json_encode($hashes, JSON_PRETTY_PRINT));
echo "基线文件已生成: {$baselineFile}\n";
}
// 用法示例
generateBaseline(__DIR__ . '/files');
该函数会递归扫描 files 目录下的所有文件,并将每个文件的完整路径及其MD5值写入 baseline.json 中。
function checkIntegrity($dir, $baselineFile = 'baseline.json') {
if (!file_exists($baselineFile)) {
echo "找不到基线文件,请先生成基线。\n";
return;
}
$baseline = json_decode(file_get_contents($baselineFile), true);
$current = [];
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($files as $file) {
if ($file->isFile()) {
$path = str_replace('\\', '/', $file->getRealPath());
$current[$path] = md5_file($path);
}
}
// 检测被修改或删除的文件
foreach ($baseline as $path => $hash) {
if (!isset($current[$path])) {
echo "[删除] {$path}\n";
} elseif ($current[$path] !== $hash) {
echo "[修改] {$path}\n";
}
}
// 检测新增的文件
foreach ($current as $path => $hash) {
if (!isset($baseline[$path])) {
echo "[新增] {$path}\n";
}
}
}
// 用法示例
checkIntegrity(__DIR__ . '/files');
这个检测脚本将新旧哈希进行对比,输出每个被修改、新增或删除的文件路径,便于开发人员及时采取措施。
可以将检测结果通过邮件、日志文件或者网页端展示出来。例如:
file_put_contents('integrity_report.log', $report);
header('Location: https://m66.net/report-viewer');
上面的代码将检测报告记录到日志文件后重定向到一个报告查看器页面,比如 https://m66.net/report-viewer。
通过 md5_file() 函数,我们可以用极少的代码构建一个高效的文件完整性检测工具。虽然它不能替代专业的安全防护工具,但对于中小型网站而言,已经足够应对常见的篡改风险。在实际部署中,建议将该脚本作为Cron任务定时运行,并结合通知机制(如邮件或钉钉机器人)进一步提高安全性。