【问题标题】:High performance method for downloading large images to PHP server from URL从 URL 下载大图像到 PHP 服务器的高性能方法
【发布时间】:2015-10-07 21:21:14
【问题描述】:

我有一个包含大约 100 个图像链接的数组。图片大小约为 5-10 MB。我想遍历数组并将所有图片下载到我的服务器。我找到了几种方法,并从 file_get_contents 开始,但它吞噬了我的记忆。

我也看过

Wget

shell_exec('wget -O /var/www/html/images/image.gif http://www.google.com/images/logo_sm.gif');

PHP 复制

copy('http://example.com/image.php', 'local/folder/flower.jpg');

CULR

$url  = 'http://www.google.com/images/logo_sm.gif';
$path = '/var/www/html/images/images.gif';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$data = curl_exec($ch);

curl_close($ch);

file_put_contents($path, $data);

每个用户都有他们“自己的”数组(不同的图片链接)。将图片下载到我的服务器并且需要最低性能(低内存使用等)的最快方法是什么

【问题讨论】:

  • 性能最低?你是说最高?

标签: php curl download wget


【解决方案1】:

时间cURL/wget/copy 接近并查看:它们将具有“大致相同”的吞吐量并且它们不会使用过多的内存1。然而,

这些新方法遇到同样的问题;下载是按顺序进行的。

(虽然涉及许多因素,包括带宽/延迟以及服务器/处理程序之间的分布,添加一定程度的并行性将是提高整体吞吐量的最大单一方法。)

wget + 并行生成

start generic parallel processes 有几种方法可以与 shell_exec 和 wget 一起使用。这些方法可以并行生成 (wget) 进程。

由于无法直接访问特定进程正在执行的操作,这也涉及到输出重定向/处理的问题。另一方面,这是对一次性 shell 执行的“相对简单”的更改。

shell exec 本身也应该针对注入攻击进行强化;使用此类 shell 访问时不应忽视安全性。

cURL + 多执行

更有利可图(最初也很复杂)的方法是使用curl_multi_exec。与curl_exec 不同,multi exec 允许 curl 以异步方式处理,因此支持并行操作。

过程有点复杂,不过a generic example can be found here;并且有一些关于 SO 的相关问题(尽管我还没有找到针对这个特定问题的“杀手级问题/答案”):

实现可能还希望限制并行 cURL 请求的数量。

我推荐使用 cURL,因为它避免了在处理 shell 时必须“格外小心”。如果必须使用 shell exec,则考虑先将文件列表/目标保存到文件中,然后通过 xargs 或其他方式将其输入。使用 cURL 还允许对单个请求进行关联反馈。

由于此操作可能会“花费一些时间”,因此下载可能应该通过队列/关闭请求机制完成..但这是蠕虫的不同架构。


1file_get_contents 的问题是它会将下载的数据作为字符串获取,这可能会导致“内存不足”的情况,具体取决于文件大小和 PHP 环境。

但是,cURL/wget/open 方法(如果正确完成)都没有这个问题,因为它们直接流式传输到文件。 (在问题中,cURL 可能会耗尽内存,因为它没有正确地流式传输到文件,而是在整个文件已经下载到内存后调用 file_put_contents。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-22
    • 2015-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多