PHP cUrl - 无法获取大文件[重复]

Posted

技术标签:

【中文标题】PHP cUrl - 无法获取大文件[重复]【英文标题】:PHP cUrl - Unable to fetch large files [duplicate] 【发布时间】:2018-05-30 09:29:01 【问题描述】:

我正在使用 php 和 cURL 开发一个 leecher 网站。

这是基本代码:

$ch = curl_init();

$url = "http://somesite.com/somefile.part1.rar";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);

$file_name = basename($url);

$output = curl_exec($ch);

curl_close($ch);

file_put_contents($file_name, $output);

当文件大小较小(例如 15MB 左右)时,此代码有效并且文件被窃取到我的服务器,但当文件大小很大(例如 1GB 左右)时,则没有任何工作。

我已尝试将 10000M 文件大小限制设置为: post_max_size 上传最大文件大小 max_file_uploads 但这没有用。

我尝试将内存限制提高到 512M 甚至 -1,但这并没有奏效。

那么如何使用 cURL 获取大文件?

【问题讨论】:

512MB ram,您必须至少有 1GB ram 才能将文件内容存储在 php 变量中然后保存,您也许应该使用 CURLOPT_FILE 并直接写入文件。脚本也可能在 60 秒后超时。 Guzzle它$client->request('GET', 'http://...', ['sink' => '/path/to/file']); 【参考方案1】:

你觉得这条线有什么作用? curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - 它告诉 php 捕获 curl_exec 的所有 stdout 输出,并立即将其全部保存在内存中,然后再执行其他任何操作,这都是一种非常缓慢的方法(因为在下载为 100 之前您不会开始写入磁盘% 完成,除非你在 SSD 上运行,否则磁盘很慢)和极度消耗内存的方法(因为你一次将整个文件存储在内存中),这些都不是可取的。相反,请执行$fp=fopen(basename($url),'wb');curl_setopt($ch,CURLOPT_FILE,$fp); - 现在 curl 会将内容直接写入磁盘,因此速度更快(在下载时将其写入磁盘)并且只需使用少量内存,无论下载文件有多大。

还要注意,如果你要同时运行大量的慢速下载,PHP-behind-a-webserver 对这项工作来说简直是一个糟糕的工具,通常你可以运行的并发 php 进程的数量非常有限,并在所有网站都忙时阻止加载整个网站,如果客户端由于某种原因断开连接,php 会中止(参见 ignore_user_abort()),如果脚本花费太长时间,许多网络服务器将超时(参见 nginx proxy_read_timeout 例如),并且 php 甚至经常因为超时原因杀死自己(参见 set_time_limit()).. 如果是这种情况,请考虑用另一种语言编写下载器(例如,Go 的 goroutines 应该能够以很少的资源进行大量并发的慢速下载用法,不像 PHP)

【讨论】:

谢谢。我按照你说的做了,而且成功了!你能告诉我你是从哪里学的,从什么书上学的吗?我在处理文件以及下载和上传文件方面做得很差,而且我正在为一个 leecher 网站开发一个项目。 @ArashNaderi 我没有真正读过书,我不记得了(2006ish,php curl docs,我想?)。顺便说一句,你有这个项目的名字吗? 谢谢。我将把它命名为“udu”,因为“你下载 uplaod” 另一个问题:当我下载一个大小为 1GB 的文件时,完成下载的时间是 3 分 20 秒,但使用 IDM,下载相同的文件大约需要 30 秒。如何在更短的时间内实现文件下载?像并行下载。 @ArashNaderi 并行下载许多连接是 PHP 非常不擅长的另一件事。 PHP CAN 使用socket api 或者curl_multi api 来做到这一点,但是socket api 很难使用,curl_multi api 使用的cpu 比它应该使用的要多(甚至正确使用 curl_multi_select & co - 不知道为什么)你会更好地使用 PHP 之外的其他工具来完成这项工作,可能是 mget 或 wget2 或 libtorrent - 但我个人可能会使用 Go-curl

以上是关于PHP cUrl - 无法获取大文件[重复]的主要内容,如果未能解决你的问题,请参考以下文章

php恢复ftp上传与curl multi

从php中的csv文件读取大数据[重复]

无法用php上传大文件

在 PHP 中获取大文件(> 2 GB)文件大小的最佳方法? [复制]

解决nginx和php使用ckfinder无法上传大文件的问题

解决nginx和php使用ckfinder无法上传大文件的问题