使用CURL作为PHP中具有多个连接和进度显示的下载管理器

7
我想使用PHP的CURL扩展创建某种下载管理器,我在想CURL是否允许实现以下两个功能:
1)多连接或多部分下载,就像普通桌面应用程序下载管理器一样。
2)不断更新屏幕上(无论是文本还是图形)的下载进度。
如果CURL for PHP允许这些功能中的任何一个,请提供一些提示。

4
PHP在多任务处理方面表现并不优秀......你应该考虑使用其他工具,否则你可能会遇到一些麻烦;-) - jldupont
许多、许多、许多的痛苦! - Shadi Almosri
@jldupont 和 Almosir:这取决于它的架构方式。如果你充分利用 Web 服务器的固有性质,构建并行、多线程和分布式应用程序非常容易。无需重新设计已经给你提供的东西(虽然在 PHP 中仍然可以做到,但可能很痛苦)。 - ChronoFish
5个回答

6
对于所有“PHP不适合多任务处理”的批评者:
请退一步考虑,如果您在LAMP环境中,那么您可以使用一个很棒的多线程框架。利用这个基本架构来发挥优势——即Apache是多线程管理器,而且非常出色。
在这种环境下,设置PHP非常容易。
  1. 将max_execution_time设置为0以允许脚本无限运行
  2. 将ignore_user_abort设置为true,即使客户端已经中止,也可以继续运行脚本
设计轻量级单任务REST web服务。以队列类型系统的方式设计它们,使其返回时间对您来说并不重要。如果使用一些基本的操作系统级互斥锁,向队列写入是线程安全的,从队列中删除也是线程安全的。
“分叉”Web服务就像打开一个文件一样简单: fclose(fopen("http://somewebservice....php?a1=v1&a2=v2&....")); // 启动 Web 服务并继续... 这种方法不仅是多线程的,而且本质上是分布式的。Web服务可以是本地的,也可以位于世界各地。PHP当然不会介意。
对于一个基本系统,唯一限制你的只有Apache允许的线程数。否则,您的代码已准备好利用负载平衡和所有其他高级Apache实现提供的所有花招。
当开发人员想到“多线程”时,往往会想到“天哪,我必须处理分叉、执行、等待和PID”。如果您按照这种方式设计系统,那么您是正确的,它会变得非常复杂。退一步并使用所给定的内容。您可以访问目录吗?Boom-您有队列。您可以发出Web调用吗?Boom-您有一个多线程(分布式)应用程序。现在根据您的应用程序将这些概念合并在一起。

多线程评论对PHP是不利的。不是一个好选择。我同意你的观点,这就是为什么我说它可以通过多种方式实现,而不仅仅是使用php,但从网络服务角度来看,这绝对是次优的选择。 - Kevin Peno
啊,我刚意识到我不小心点了踩。编辑你的答案,这样我就可以改变投票了 :) - Kevin Peno
有何方面不够优化?服务器负载?他等待Curl调用的时间比等待任何类型的开销并行Web服务的时间长。当然,你必须使用不止“仅仅”PHP - 工具都在那里 - 使用它们。这并不会使它成为一个“PHP”解决方案。 - ChronoFish
服务器负载并不是这里的问题。连接限制将会发挥作用。这就是为什么专门的服务器被创建,用于需要客户端和服务器之间长时间并发连接的任何事情。此外,您将在您的方法中使用“http请求”来模拟php中的多线程,而您可以选择支持多线程的语言并删除该黑客。您可以做到这一点,当然,但有更加优化的方法来完成任务。然后,您将获得与这些子进程交流并从中获取信息的工具。 - Kevin Peno

1

PHP 不支持多线程,如果通过多次文件调用或者分叉等方式试图强制实现多线程,通常会导致结果低效。我建议不要这样做,尽管如此,可以通过混合使用 js、php(可能不包括 curl 但是可以使用自定义的 php 文件流),以及长轮询等方法来实现类似多线程的功能。


在繁忙的网站上进行长轮询将迅速消耗您可用的Web服务器连接计数。不过,仅使用PHP并没有太多其他选择。 - Daren Schwenke
就像我所说的,我建议不要这样做,这样做会是次优的。但是它是可能的 ;) - Kevin Peno

0
不,情况并非如此。这是不可能的,因为下载管理器会调用处理下载的类5次 - 这是PHP类实例。
这是一个示例类调用:
$tr = new teConnections();
$data = $tr->downloadManager(array('http', 'host', path', 'login', 'pass', 'port'), 'file name, compression, streaming); 

0

这是可能的,看看curl_multi_init();


0

这是正确的,但你必须同时初始化所有下载。当我想到下载管理器时,我会将停止、启动、添加、删除等视为功能。Curl 无法单独完成此操作,PHP 也不能。 - Kevin Peno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接