在日常的运维或网站管理中,我们经常会遇到这样一个需求:监控FTP服务器上的某个目录文件是否有新增、修改或删除操作。虽然可以使用文件同步工具或者高级监控系统来实现,但如果我们希望用一种更轻量、灵活的方式实现目录快照比对,PHP 提供的 ftp_rawlist 函数便是一种非常实用的方案。
ftp_rawlist 是 PHP 提供的 FTP 操作函数之一,它允许我们获取远程目录的原始目录列表。相比于 ftp_nlist 只返回文件名,ftp_rawlist 返回的是类似 Unix ls -l 命令输出的详细信息,包括权限、文件大小、时间戳等。
通过对两个时点抓取的 ftp_rawlist 结果进行比对,我们就可以轻松实现“目录快照”对比,识别哪些文件发生了变化。
连接FTP服务器并登录
抓取目标目录的文件列表(即快照)
保存快照到本地文件
在下一次运行时重新抓取,并与上次快照对比
输出变动内容(新增、删除、修改)
以下是一个完整的PHP脚本示例,演示如何抓取FTP快照并与上次快照进行比对:
<code> ```php <?php// FTP 配置
$ftp_host = "ftp.gitbox.net";
$ftp_user = "ftp_user";
$ftp_pass = "ftp_password";
$ftp_dir = "/htdocs/";
$snapshot_file = DIR . '/last_snapshot.txt';
// 连接并登录
$conn = ftp_connect($ftp_host);
if (!$conn) {
die("无法连接FTP服务器");
}
if (!ftp_login($conn, $ftp_user, $ftp_pass)) {
ftp_close($conn);
die("FTP登录失败");
}
// 获取当前快照
ftp_chdir($conn, $ftp_dir);
$rawlist = ftp_rawlist($conn, ".");
ftp_close($conn);
// 解析快照成结构化数组
function parse_rawlist($rawlist) {
$snapshot = [];
foreach ($rawlist as $line) {
$parts = preg_split("/\s+/", $line, 9);
if (count($parts) < 9) continue;
$name = $parts[8];
$info = [
'perm' => $parts[0],
'size' => $parts[4],
'date' => "{$parts[5]} {$parts[6]} {$parts[7]}"
];
$snapshot[$name] = $info;
}
return $snapshot;
}
$current_snapshot = parse_rawlist($rawlist);
// 加载上次快照
$previous_snapshot = file_exists($snapshot_file) ? unserialize(file_get_contents($snapshot_file)) : [];
// 对比快照
$added = array_diff_key($current_snapshot, $previous_snapshot);
$deleted = array_diff_key($previous_snapshot, $current_snapshot);
$modified = [];
foreach ($current_snapshot as $file => $info) {
if (isset($previous_snapshot[$file])) {
if ($info['size'] !== $previous_snapshot[$file]['size'] ||
$info['date'] !== $previous_snapshot[$file]['date']) {
$modified[$file] = $info;
}
}
}
// 输出变动结果
echo "=== 文件变动报告 ===\n";
if ($added) {
echo "\n[新增文件]:\n";
foreach ($added as $file => $info) {
echo " + $file\n";
}
}
if ($deleted) {
echo "\n[删除文件]:\n";
foreach ($deleted as $file => $info) {
echo " - $file\n";
}
}
if ($modified) {
echo "\n[修改文件]:\n";
foreach ($modified as $file => $info) {
echo " * $file\n";
}
}
// 保存当前快照
file_put_contents($snapshot_file, serialize($current_snapshot));
</code>
## 四、实用建议
1. **定时执行**:可通过 `cron` 或 Windows 任务计划每小时/每天运行一次脚本,定期生成快照。
2. **通知机制**:可以将变动信息通过邮件或Webhook方式发送通知,及时获知风险操作。
3. **过滤规则**:脚本中可加入白名单或忽略规则,例如跳过 `.log`、`.tmp` 文件。
## 五、总结
通过 `ftp_rawlist` 获取目录原始结构,再加以结构化、序列化和对比,我们可以用极小的成本实现类似“目录监控”的功能。这种方式特别适用于小型项目、老旧系统、或仅需临时监控的场景。既节省资源,又灵活高效,是PHP在轻量级自动化中的一个实用“黑科技”。