从 URL 下载大图像到 PHP 服务器的高性能方法
High performance method for downloading large images to PHP server from URL
我有一个包含大约 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);
每个用户都有自己的 "own" 数组(不同的图像链接)。将图片下载到我的服务器并要求最低性能(低内存使用率等)的最快方法是什么
计时 cURL/wget/copy
方法并查看:它们将具有 "roughly the same" 吞吐量并且不会使用过多内存1。然而,
这些新方法遇到同样的问题;下载按顺序进行。
(虽然涉及许多因素,包括 bandwidth/latency 和 servers/handlers 之间的分布, 添加一定程度的并行性将是改进总吞吐量.)
wget + 并行生成
start generic parallel processes 有几种方法可以与 shell_exec 和 wget 一起使用。这些方法可以并行生成 (wget) 进程。
由于无法直接访问特定进程正在执行的操作,因此还涉及欺骗输出 redirection/processing。另一方面,它是一次 'relatively simple' 一次 shell 执行的更改。
shell exec 本身也应该针对注入攻击进行加固;使用此类 shell 访问权限时,不应降低安全性。
cURL + 多执行
更有利可图(并且最初很复杂)的方法是使用 curl_multi_exec
。与curl_exec
不同,multi exec允许以异步方式处理curl,从而支持并行操作。
过程有点曲折,但是a generic example can be found here;还有一些关于 SO 的相关问题(尽管我还没有找到针对这个特定问题的 'killer question/answer'):
- understanding php curl_multi_exec
- Fastest way to download multiple urls
实现可能还想限制并行 cURL 请求的数量。
我推荐 cURL,因为它避免了在处理 shell 时必须是 'extra careful'。如果必须使用 shell exec,那么考虑先将文件 list/targets 保存到一个文件中,然后通过 xargs
或诸如此类的东西将其输入。使用 cURL 还允许对单个请求进行关联反馈。
由于此操作可能绑定到 'take some time',因此下载可能应该通过队列/非请求机制来完成。但那是一种不同的蠕虫架构。
1 file_get_contents
的问题是它将下载的数据作为字符串获取,这可能导致 'out of memory' 条件,具体取决于文件大小和 PHP环境。
但是,none 的 cURL/wget/open 方法(如果正确完成)在直接流式传输到文件时会遇到此问题。 (在这个问题中,cURL 可能 运行 内存不足,因为它没有正确地流式传输到文件,而是在整个文件已经下载到内存中后调用 file_put_contents
。)
我有一个包含大约 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);
每个用户都有自己的 "own" 数组(不同的图像链接)。将图片下载到我的服务器并要求最低性能(低内存使用率等)的最快方法是什么
计时 cURL/wget/copy
方法并查看:它们将具有 "roughly the same" 吞吐量并且不会使用过多内存1。然而,
这些新方法遇到同样的问题;下载按顺序进行。
(虽然涉及许多因素,包括 bandwidth/latency 和 servers/handlers 之间的分布, 添加一定程度的并行性将是改进总吞吐量.)
wget + 并行生成
start generic parallel processes 有几种方法可以与 shell_exec 和 wget 一起使用。这些方法可以并行生成 (wget) 进程。
由于无法直接访问特定进程正在执行的操作,因此还涉及欺骗输出 redirection/processing。另一方面,它是一次 'relatively simple' 一次 shell 执行的更改。
shell exec 本身也应该针对注入攻击进行加固;使用此类 shell 访问权限时,不应降低安全性。
cURL + 多执行
更有利可图(并且最初很复杂)的方法是使用 curl_multi_exec
。与curl_exec
不同,multi exec允许以异步方式处理curl,从而支持并行操作。
过程有点曲折,但是a generic example can be found here;还有一些关于 SO 的相关问题(尽管我还没有找到针对这个特定问题的 'killer question/answer'):
- understanding php curl_multi_exec
- Fastest way to download multiple urls
实现可能还想限制并行 cURL 请求的数量。
我推荐 cURL,因为它避免了在处理 shell 时必须是 'extra careful'。如果必须使用 shell exec,那么考虑先将文件 list/targets 保存到一个文件中,然后通过 xargs
或诸如此类的东西将其输入。使用 cURL 还允许对单个请求进行关联反馈。
由于此操作可能绑定到 'take some time',因此下载可能应该通过队列/非请求机制来完成。但那是一种不同的蠕虫架构。
1 file_get_contents
的问题是它将下载的数据作为字符串获取,这可能导致 'out of memory' 条件,具体取决于文件大小和 PHP环境。
但是,none 的 cURL/wget/open 方法(如果正确完成)在直接流式传输到文件时会遇到此问题。 (在这个问题中,cURL 可能 运行 内存不足,因为它没有正确地流式传输到文件,而是在整个文件已经下载到内存中后调用 file_put_contents
。)