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

使用PHP copy函数跨服务器复制大文件失败求助

解决PHP复制大文件后损坏的问题

先排查权限问题

不一定是权限,但先快速排除:

  • 检查datafile目录的权限:确保运行PHP的用户(通常是www-data、apache或nginx)有写入权限。可以用命令行执行chmod 755 datafile(给所有用户读/执行权限,所有者写权限),或者chown www-data:www-data datafile(把目录所有权转给PHP进程用户)。
  • 对比本地生成的文件大小和原文件(10GB):如果本地文件远小于10GB,说明是传输中断/未完成,不是权限问题;如果大小一致但仍损坏,再考虑权限或文件系统问题。

为什么copy()函数会失败?

copy()函数仅适合小文件,处理大文件时容易触发以下问题:

  • PHP的max_execution_time限制:默认执行时间通常是30秒,10GB文件下载远超这个时间,会被强制中断导致文件不完整。
  • 内存限制:copy()会尝试把文件内容加载到内存,大文件直接撑爆memory_limit。
  • 网络不稳定:无断点续传机制,中途断连后文件直接损坏。

可行解决方案

方案1:用cURL流式下载(推荐,稳定且可控)

cURL支持流式传输,不会一次性加载整个文件到内存,还能设置超时、跟随跳转等:

<?php
// 源文件URL
$remote_file_url = 'http://speedtest.tele2.net/10GB.zip';
// 本地保存路径
$local_file = 'datafile/DL-10GB.zip';

// 临时调整PHP执行限制(避免超时)
ini_set('max_execution_time', 0); // 0表示无时间限制,也可设36000(10小时)
ini_set('memory_limit', '256M'); // 流式下载内存占用低,256M足够

// 初始化cURL
$ch = curl_init($remote_file_url);
// 打开本地文件句柄
$fp = fopen($local_file, 'wb');

// 设置cURL选项
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
curl_setopt($ch, CURLOPT_TIMEOUT, 0); // 无超时限制
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0'); // 模拟浏览器UA,避免被源站拦截

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

// 关闭资源
fclose($fp);
curl_close($ch);

// 检查结果
if (!$success) {
    echo "下载失败:" . curl_error($ch);
} else {
    // 可选:验证文件完整性(源站10GB.zip的SHA256哈希值:53d6fe6b4d79938e48780a42e81b0578500d45e407412f91a9ed2b439425d3f5)
    $local_hash = hash_file('sha256', $local_file);
    $source_hash = '53d6fe6b4d79938e48780a42e81b0578500d45e407412f91a9ed2b439425d3f5';
    if ($local_hash === $source_hash) {
        echo "下载成功且文件完整!";
    } else {
        echo "下载完成但文件损坏,请重新下载!";
    }
}
?>

方案2:用PHP原生fopen分段读写

如果服务器未启用cURL,可以用分段读写的方式,每次读取一小块数据写入本地:

<?php
$remote_file_url = 'http://speedtest.tele2.net/10GB.zip';
$local_file = 'datafile/DL-10GB.zip';

ini_set('max_execution_time', 0);
ini_set('memory_limit', '256M');

// 打开远程文件(需开启allow_url_fopen)
$remote_fp = fopen($remote_file_url, 'rb');
if (!$remote_fp) {
    die("无法打开远程文件");
}

// 打开本地文件
$local_fp = fopen($local_file, 'wb');
if (!$local_fp) {
    fclose($remote_fp);
    die("无法创建本地文件");
}

// 分段读写,每次1MB
$chunk_size = 1024 * 1024;
while (!feof($remote_fp)) {
    $chunk = fread($remote_fp, $chunk_size);
    fwrite($local_fp, $chunk);
}

// 关闭资源
fclose($remote_fp);
fclose($local_fp);

// 验证完整性
$local_hash = hash_file('sha256', $local_file);
$source_hash = '53d6fe6b4d79938e48780a42e81b0578500d45e407412f91a9ed2b439425d3f5';
if ($local_hash === $source_hash) {
    echo "下载成功且文件完整!";
} else {
    echo "下载完成但文件损坏,请重新下载!";
}
?>

额外注意事项

  • 确保服务器开启allow_url_fopen(方案2需要),或者开启cURL扩展(方案1需要),可通过phpinfo()查看配置。
  • 检查服务器磁盘空间是否足够(至少10GB剩余)。
  • 大文件下载建议用CLI模式后台执行,避免网页超时中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:41:00