【问题标题】:CURL as a download manager with multiple connections and progress display in PHPCURL 作为下载管理器,在 PHP 中具有多个连接和进度显示
【发布时间】:2009-10-23 14:41:23
【问题描述】:

我想使用 PHP 的 CURL 扩展来创建某种下载管理器,我在想 CURL 是否允许实现我正在考虑的这两个功能:

1) 与普通桌面应用程序下载管理器一样的多连接或多部分下载。

2) 在屏幕上不断更新(文本或图形,无关紧要)下载进度。

CURL for PHP 允许这些吗?如果是这样,是否愿意提供一些提示?

【问题讨论】:

  • PHP 并不擅长多任务处理...您应该考虑使用其他东西,否则您可能会因为一些痛苦而签约 ;-)
  • 很多很多很多的痛苦!
  • @jldupont & Almosir:取决于它的架构方式。如果您利用 Web 服务器的固有特性,则可以非常轻松地构建并行、多线程、分布式应用程序。没有必要重新设计已经给你的东西(这在 PHP 中仍然是可行的(虽然很痛苦))

标签: php curl download


【解决方案1】:

致所有“PHP 不适合多任务处理”的批评者:

退一步考虑一下,如果您在 LAMP 环境中,您可以使用一个很棒的多线程框架。使用这个基础架构来发挥你的优势 - 即 Apache 是多线程管理器 - 并且在这方面非常出色。

设置 PHP 以在这种环境中工作非常容易。

  1. 设置 max_execution_time = 0 以允许脚本无限期运行
  2. 设置 ignore_user_abort = true 以允许脚本即使在 客户端已中止

设计轻量级单任务 REST Web 服务。以这样一种方式设计它们,当它们返回时你不在乎,例如在队列类型系统中。写入队列是线程安全的,如果使用一些基本的操作系统级别的互斥锁,从队列中删除是线程安全的。

“分叉”网络服务就像打开一个文件一样简单:

fclose(fopen("http://somewebservice....php?a1=v1&a2=v2&....")); // Launch a web service and continue...

这种方法不仅是多线程的,而且本质上也是分布式的。 Web 服务可以是本地的,也可以位于世界各地。 PHP当然不在乎。

对于一个基本系统来说,唯一阻碍你的是 apache 允许的线程数。否则,您的代码就可以利用负载平衡以及高级 Apache 实现必须提供的所有其他巧妙技巧。

当开发人员认为“多线程”时,他们常常认为“我的天啊,我必须处理 fork 和 exec 以及等待和 PID”。如果你以这种方式设计你的系统——你是对的,它很快就会变得非常复杂。退后一步,使用给定的东西。您有权访问目录吗?繁荣 - 你有队列。可以发出网络电话吗? Boom - 你有一个多线程(分布式)应用程序。现在只需按照您的应用要求将这些概念合并在一起即可。

【讨论】:

  • 多线程 cmets 是针对 PHP 的。不是栈。我同意你的观点,这就是为什么我说它可以通过多种方式使用,而不仅仅是使用 php,但从 Web 服务的角度来看,这绝对是次优的。
  • 呸,我才意识到我投了反对票。编辑您的答案,以便我可以更改投票:)
  • 以何种方式次优?服务器负载?他将等待他的 Curl 调用,而不是等待任何类型的并行 Web 服务创建的开销。当然,你必须使用的不仅仅是“只是”PHP——工具就在那里——使用它们。不会使它不再是一个“PHP”解决方案。
  • 服务器负载在这里并不是真正的问题。连接限制将发挥作用。这就是为任何需要在客户端和服务器之间建立持久并发连接的东西创建特殊服务器的原因。此外,当您只需选择一种支持多线程的语言并删除 hack 时,您将在您的方法中使用“http 请求”淹没服务器,只是为了在 php 中模拟多线程。当然,你可以做到,但完成任务还有更优化的方法。然后,您将获得与这些子进程对话并从中获取信息的工具。
【解决方案2】:

PHP 不是多线程的,如果你试图通过多个文件调用或分叉来强制它,结果通常是次优的。我建议不要这样做,但是,可以混合使用 js、php(可能不是 curl,而是自定义 php file stream)和 long polling

【讨论】:

  • 在繁忙的站点上进行长时间轮询会很快消耗您的可用网络服务器连接数。不过,你只能用 php 做的不多。
  • 就像我说的,我建议不要这样做,这将是次优的。但这是可能的;)
【解决方案3】:

curl_multi_xyz() 函数,如curl_multi_exec() 允许您同时处理多个请求。如果您想并行下载同一文件的多个分段,还请查看CURLOPT_RANGE。 您可以使用CURLOPT_READFUNCTIONCURLOPT_WRITEFUNCTION 设置的回调函数将允许您向客户端发送某种进度数据。

【讨论】:

  • 确实如此,但您必须同时初始化所有下载。当我想到下载管理器时,我将停止、启动、添加、删除等视为功能。 Curl 自己做不到,php 也做不到。
【解决方案4】:

有可能,看看 curl_multi_init();

【讨论】:

    【解决方案5】:

    不,事实并非如此。这是不可能的,因为下载管理器调用了处理下载 5 次的类——即 PHP 类实例。

    这是一个示例类调用:

    $tr = new teConnections();
    $data = $tr->downloadManager(array('http', 'host', path', 'login', 'pass', 'port'), 'file name, compression, streaming); 
    

    【讨论】:

      猜你喜欢
      • 2013-01-25
      • 1970-01-01
      • 2012-12-07
      • 2023-03-20
      • 2010-12-28
      • 1970-01-01
      • 2014-11-18
      • 1970-01-01
      • 2015-05-25
      相关资源
      最近更新 更多