在使用 PHP 通过 FTP 协议操作远程服务器时,ftp_rawlist() 是一个常用函数,它可以返回类似于 Unix 系统 ls -l 命令的输出结果。尽管这些原始输出提供了完整的文件列表信息,但由于其格式为纯文本字符串,要从中提取出如文件大小、修改时间这样的具体信息,则需要一些额外处理。
本文将介绍如何通过解析 ftp_rawlist() 的输出,提取每个文件的大小和最后修改时间,并附带示例代码。
ftp_rawlist() 返回的是一个字符串数组,每个元素表示一个文件或目录的信息,格式如下:
-rw-r--r-- 1 user group 1048576 May 21 13:37 filename.zip
drwxr-xr-x 2 user group 512 May 20 10:15 subdir
每一行是一个用空格分隔的字符串,包含了文件类型、权限、链接数、所有者、组、大小、修改日期与时间、以及文件名。
要提取文件大小和修改时间,可以用正则表达式将这些字段解析出来。
<?php
// 连接 FTP
$ftp = ftp_connect("gitbox.net");
ftp_login($ftp, "username", "password");
// 获取目录列表
$rawList = ftp_rawlist($ftp, ".");
// 遍历并解析每一行
foreach ($rawList as $line) {
if (preg_match('/^([\-ld])([rwx\-]{9})\s+\d+\s+\S+\s+\S+\s+(\d+)\s+([A-Za-z]{3})\s+(\d{1,2})\s+(\d{2}:\d{2}|\d{4})\s+(.*)$/', $line, $matches)) {
$type = $matches[1];
$size = $matches[3];
$month = $matches[4];
$day = $matches[5];
$timeOrYear = $matches[6];
$name = $matches[7];
// 将修改时间转换为时间戳
$currentYear = date("Y");
$fileTimeStr = "$month $day $timeOrYear";
if (strpos($timeOrYear, ':') !== false) {
// 说明是当天的时间,年份为当前年
$fileTimeStr .= " $currentYear";
$timestamp = strtotime($fileTimeStr);
} else {
// 时间为年份
$timestamp = strtotime("$month $day $timeOrYear");
}
echo "文件: $name\n";
echo "类型: " . ($type === 'd' ? '目录' : '文件') . "\n";
echo "大小: $size 字节\n";
echo "修改时间: " . date("Y-m-d H:i:s", $timestamp) . "\n";
echo "-----------------------------\n";
}
}
ftp_close($ftp);
?>
ftp_rawlist() 的格式依赖于远程服务器的操作系统类型,上面的正则针对的是 Unix 风格的列表结果。如果服务器使用的是 Windows FTP,输出格式将完全不同,需要根据实际情况调整。
解析过程中建议始终进行正则匹配的错误处理,以防止格式不符引起的问题。
对于跨时区的服务器,strtotime() 转换的结果可能会有误差,建议使用 DateTime 类和时区对象更精确地处理时间。
通过上述方法,您就可以轻松地从 ftp_rawlist() 的结果中提取出文件大小与修改时间,并将其用于文件同步、日志分析等场景。