You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP环境下FTP大文件下载提速咨询:1GB文件需从1小时降至20分钟内

优化PHP大文件FTP下载速度的方案

针对你用原生PHP FTP函数下载1GB大文件耗时超1小时的问题,结合高配置服务器和带宽的前提,以下是几个能将下载时间压缩到15-20分钟内的优化方案:


1. 启用FTP被动模式并调整缓冲区大小

原生ftp_connect默认使用主动模式,容易被防火墙或路由规则限制,导致传输速率低下。同时默认缓冲区过小也会拖慢传输效率。

修改后的代码:

<?php
// FTP server details
$ftp_server = "ftp.example.com";
$ftp_username = "username";
$ftp_userpass = "password";
$remote_file = "/path/to/remote/file.txt";
$local_file = "/path/to/local/file.txt";

// Establish an FTP connection
$conn_id = ftp_connect($ftp_server) or die("Could not connect to $ftp_server");

// 调整传输缓冲区为1MB(默认通常为8KB)
ftp_set_option($conn_id, FTP_BUFFERSIZE, 1024 * 1024);

// Login to FTP server
if (@ftp_login($conn_id, $ftp_username, $ftp_userpass)) {
    echo "Connected to $ftp_server as $ftp_username\n";
    
    // 启用被动模式,避免防火墙拦截数据连接
    ftp_pasv($conn_id, true);

    // Download the remote file and save it to the local file
    if (ftp_get($conn_id, $local_file, $remote_file, FTP_BINARY)) {
        echo "Successfully downloaded $remote_file to $local_file\n";
    } else {
        echo "There was a problem while downloading $remote_file to $local_file\n";
    }
} else {
    echo "Could not login to $ftp_server\n";
}

// Close the FTP connection
ftp_close($conn_id);
?>

说明:被动模式让客户端主动发起数据连接,规避主动模式下的防火墙限制;增大缓冲区减少磁盘IO次数,提升传输效率。


2. 用cURL替代原生FTP函数

cURL的FTP实现优化更完善,支持更多底层参数调整,传输效率普遍高于原生PHP FTP函数。

示例代码:

<?php
$ftp_server = "ftp.example.com";
$ftp_username = "username";
$ftp_userpass = "password";
$remote_file = "/path/to/remote/file.txt";
$local_file = "/path/to/local/file.txt";

$remote_url = "ftp://$ftp_username:$ftp_userpass@$ftp_server$remote_file";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remote_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// 启用被动模式
curl_setopt($ch, CURLOPT_FTP_USE_EPSV, true);
// 设置1MB缓冲区
curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024 * 1024);
// 直接写入本地文件,避免内存占用
$fp = fopen($local_file, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);

// 执行下载
$success = curl_exec($ch);

if (!$success) {
    echo "Download failed: " . curl_error($ch) . "\n";
} else {
    echo "Successfully downloaded $remote_file to $local_file\n";
}

// 清理资源
fclose($fp);
curl_close($ch);
?>

说明:cURL直接将数据写入文件,避免内存溢出,同时底层优化的传输逻辑能有效提升速率。


3. 多线程分片下载(最大化带宽利用)

单连接FTP传输受限于协议本身的单流速率,分片多线程下载可以同时建立多个连接,充分利用带宽资源。

以下是基于curl_multi的多线程分片下载示例:

<?php
$ftp_server = "ftp.example.com";
$ftp_username = "username";
$ftp_userpass = "password";
$remote_file = "/path/to/remote/file.txt";
$local_file = "/path/to/local/file.txt";
$chunk_size = 1024 * 1024 * 100; // 每个分片100MB

// 获取远程文件大小
$conn_id = ftp_connect($ftp_server);
ftp_login($conn_id, $ftp_username, $ftp_userpass);
ftp_pasv($conn_id, true);
$file_size = ftp_size($conn_id, $remote_file);
ftp_close($conn_id);

if ($file_size == -1) {
    die("Failed to get remote file size\n");
}

$total_chunks = ceil($file_size / $chunk_size);
$chunks = [];
$mh = curl_multi_init();

// 创建每个分片的下载请求
for ($i = 0; $i < $total_chunks; $i++) {
    $start = $i * $chunk_size;
    $end = min(($i + 1) * $chunk_size - 1, $file_size - 1);
    $chunk_file = "$local_file.part$i";
    
    $ch = curl_init();
    $url = "ftp://$ftp_username:$ftp_userpass@$ftp_server$remote_file";
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RANGE, "$start-$end");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
    curl_setopt($ch, CURLOPT_FTP_USE_EPSV, true);
    
    $fp = fopen($chunk_file, 'wb');
    curl_setopt($ch, CURLOPT_FILE, $fp);
    
    curl_multi_add_handle($mh, $ch);
    $chunks[] = ['ch' => $ch, 'fp' => $fp, 'file' => $chunk_file];
}

// 执行多连接下载
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);

// 合并分片文件
$final_fp = fopen($local_file, 'wb');
foreach ($chunks as $chunk) {
    fseek($chunk['fp'], 0);
    stream_copy_to_stream($chunk['fp'], $final_fp);
    fclose($chunk['fp']);
    curl_multi_remove_handle($mh, $chunk['ch']);
    unlink($chunk['file']);
}
fclose($final_fp);
curl_multi_close($mh);

echo "Successfully downloaded and merged $remote_file to $local_file\n";
?>

说明:将大文件拆分为多个分片并行下载,完成后合并为完整文件。注意需确保FTP服务器支持RANGE请求(大部分主流FTP服务器都支持)。


内容的提问来源于stack exchange,提问作者Raja N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:53:20