php实现ftp下载
使用PHP内置FTP函数实现下载
PHP提供了一系列内置FTP函数,无需额外安装扩展即可实现基本FTP操作。以下是通过ftp_get()函数实现文件下载的典型流程:
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
$remote_file = "/path/to/remote/file.txt";
$local_file = "localfile.txt";
$conn = ftp_connect($ftp_server) or die("Could not connect to $ftp_server");
if (ftp_login($conn, $ftp_user, $ftp_pass)) {
ftp_pasv($conn, true); // 启用被动模式
if (ftp_get($conn, $local_file, $remote_file, FTP_BINARY)) {
echo "File downloaded successfully";
} else {
echo "Error downloading file";
}
}
ftp_close($conn);
使用cURL库实现FTP下载
对于需要更复杂控制的场景,cURL提供了更灵活的FTP操作方式:
$remote_url = "ftp://username:password@ftp.example.com/path/to/file.txt";
$local_path = "downloaded_file.txt";
$fp = fopen($local_path, 'w');
$ch = curl_init($remote_url);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FTP_USE_EPSV, true); // 使用EPSV模式
curl_setopt($ch, CURLOPT_TIMEOUT, 300); // 超时设置
$result = curl_exec($ch);
curl_close($ch);
fclose($fp);
if ($result) {
echo "File downloaded via cURL";
}
处理大文件下载
对于大文件下载,建议采用流式处理并显示进度:
$ftp = ftp_connect("ftp.example.com");
ftp_login($ftp, "user", "pass");
ftp_pasv($ftp, true);
$remote_size = ftp_size($ftp, "largefile.zip");
$handle = fopen("local_copy.zip", "w");
$start_time = time();
$last_print = 0;
ftp_nb_get($ftp, "local_copy.zip", "largefile.zip", FTP_BINARY, function($downloaded) use ($remote_size, $start_time, &$last_print) {
if (time() - $last_print > 1) { // 每秒更新一次进度
$percent = round(($downloaded/$remote_size)*100, 2);
$elapsed = time() - $start_time;
$speed = $elapsed > 0 ? round($downloaded/1024/$elapsed, 2) : 0;
echo "Downloaded: $percent% ($speed KB/s)\n";
$last_print = time();
}
});
ftp_close($ftp);
fclose($handle);
安全注意事项
FTP协议默认不加密传输,敏感数据应考虑使用FTPS(FTP over SSL)或SFTP(SSH File Transfer Protocol)。PHP的ftp_ssl_connect()函数支持FTPS:
$conn = ftp_ssl_connect("ftp.example.com");
if ($conn && ftp_login($conn, "user", "pass")) {
ftp_get($conn, "local.txt", "remote.txt", FTP_BINARY);
ftp_close($conn);
}
错误处理与重试机制
稳健的实现应包含错误处理和自动重试:
function ftpDownloadWithRetry($host, $user, $pass, $remote, $local, $retries = 3) {
for ($i = 0; $i < $retries; $i++) {
try {
$ftp = ftp_connect($host);
if (!ftp_login($ftp, $user, $pass)) throw new Exception("Login failed");
ftp_pasv($ftp, true);
if (ftp_get($ftp, $local, $remote, FTP_BINARY)) {
ftp_close($ftp);
return true;
}
} catch (Exception $e) {
if (isset($ftp)) ftp_close($ftp);
if ($i == $retries - 1) throw $e;
sleep(pow(2, $i)); // 指数退避
}
}
return false;
}






