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

PHP从URL下载大文件至服务器遇阻,寻求后台续传代码

解决PHP大文件后台下载(关闭浏览器也能完成)的问题

嘿,我来帮你搞定这个大文件下载的坑!你的代码之所以下载1GB文件到100MB就失败,核心问题出在file_get_contents上——它会把整个远程文件一次性加载到内存里,而PHP默认的内存限制一般也就128MB左右,内存撑爆了自然就断了。哪怕你开了ignore_user_abort(true),内存瓶颈没解决还是白搭。

下面给你一套专门针对大文件的后台下载方案,既能避免内存溢出,又能保证用户关闭浏览器后脚本继续跑完:

<?php
// 开启后台执行:用户关闭浏览器后脚本继续运行
ignore_user_abort(true);
// 取消脚本执行时间限制(大文件下载需要足够时间,也可以设成具体值比如86400=24小时)
set_time_limit(0);

// 替换成你的远程文件URL和本地保存路径
$remote_file_url = 'http://domain/id.mp4';
$local_save_path = 'file.mp4';

// 打开远程文件流(只读二进制模式)
$remote_handle = fopen($remote_file_url, 'rb');
if (!$remote_handle) {
    die('无法连接到远程文件,请检查URL是否正确');
}

// 打开本地文件流(追加二进制模式,中途中断后可以续传)
$local_handle = fopen($local_save_path, 'ab');
if (!$local_handle) {
    fclose($remote_handle);
    die('无法创建/打开本地文件,请检查路径权限');
}

// 每次读取的块大小,建议4MB-16MB,平衡内存占用和下载效率
$chunk_size = 4 * 1024 * 1024; // 4MB

// 逐块读取远程文件并写入本地
while (!feof($remote_handle)) {
    // 读取一块数据
    $chunk_data = fread($remote_handle, $chunk_size);
    if ($chunk_data === false) {
        break; // 读取失败就退出循环
    }
    // 写入本地文件
    fwrite($local_handle, $chunk_data);
    // 立即刷新缓冲区,确保数据写入磁盘(避免缓存丢失)
    fflush($local_handle);
}

// 关闭文件句柄,释放资源
fclose($remote_handle);
fclose($local_handle);

echo '大文件下载完成啦!';
?>

关键细节说明:

  • 文件流方式处理:用fopen+fread+fwrite逐块操作,内存只占用你设置的chunk_size大小,再也不会因为大文件耗尽内存。
  • 后台执行保障:ignore_user_abort(true)确保用户关闭浏览器后,服务器端的脚本依然会继续执行完下载任务。
  • 无时间限制:set_time_limit(0)取消了PHP脚本的执行时间上限,不用担心大文件下载到一半超时。
  • 断点友好:用ab模式打开本地文件,如果下载中途意外中断,再次运行脚本可以从已经下载的位置继续(如果需要更完善的断点续传,可以额外加逻辑:先获取本地文件大小,然后给远程请求加Range头读取剩余部分)。

额外注意事项:

  1. 确保PHP配置里的allow_url_fopen是开启状态(可以在php.ini里设置allow_url_fopen = On,或者代码里尝试ini_set('allow_url_fopen', 1))。
  2. 检查本地保存路径的读写权限,确保PHP进程能创建和写入文件。
  3. 如果服务器有open_basedir限制,要把本地保存路径加到允许的目录里。
  4. 对于超大文件(比如几十GB),可以考虑加个日志功能,记录下载进度和可能的错误,方便排查问题。

内容的提问来源于stack exchange,提问作者Seeking help

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:33:33