当我对 10 个 url 运行检查时,如果我能够与主机服务器建立连接,句柄将返回一条成功消息 (CURLE_OK)
如果服务器拒绝连接,在处理每个句柄时,句柄将包含一条错误消息。
问题
我假设当我们得到一个错误的句柄时,CURL 将标记这个句柄但继续处理未处理的句柄,然而这似乎不是发生的事情。 当我们遇到坏句柄时,CURL 会将此句柄标记为坏句柄,但不会处理其余未处理的句柄。
这可能很难检测到,如果我确实获得了与所有句柄的连接(这是大多数情况下发生的情况),那么问题就不明显了。(CURL 仅在第一个错误连接时停止);
为了测试,我必须找到一个合适的网站,该网站加载缓慢/拒绝 x 数量的同时连接。
set_time_limit(0);
$l = array(
'http://smotri.com/video/list/',
'http://smotri.com/video/list/sports/',
'http://smotri.com/video/list/animals/',
'http://smotri.com/video/list/travel/',
'http://smotri.com/video/list/hobby/',
'http://smotri.com/video/list/gaming/',
'http://smotri.com/video/list/mult/',
'http://smotri.com/video/list/erotic/',
'http://smotri.com/video/list/auto/',
'http://smotri.com/video/list/humour/',
'http://smotri.com/video/list/film/'
);
$mh = curl_multi_init();
$s = 0;
$f = 10;
while($s <= $f)
{
$ch = curl_init();
$curlsettings = array(
CURLOPT_URL => $l[$s],
CURLOPT_TIMEOUT => 0,
CURLOPT_CONNECTTIMEOUT => 0,
CURLOPT_RETURNTRANSFER => 1
);
curl_setopt_array($ch, $curlsettings);
curl_multi_add_handle($mh,$ch);
$s++;
}
$active = null;
do
{
curl_multi_exec($mh,$active);
curl_multi_select($mh);
$info = curl_multi_info_read($mh);
echo '<pre>';
var_dump($info);
if($info['result'] === CURLE_OK)
echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' success<br>';
if($info['result'] != 0)
echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' failed<br>';
} while ($active > 0);
curl_multi_close($mh);
我已将 $info 转储到脚本中,该脚本会询问多 handle 在运行时是否有关于任何 handle 的任何新信息。 当脚本结束时,我们将看到一些 bool(false) - 当没有新信息可用时(句柄仍在处理中),以及所有句柄(如果全部成功)或有限句柄(如果一个句柄失败)。
我没能解决这个问题,这可能是我忽略了的事情,而且我在尝试解决不相关的问题上走得太远了。
一些解决此问题的尝试是。
将每个 $ch 句柄分配给一个数组 - $ch[1]、$ch[2] 等(而不是 将当前 $ch 句柄添加到 multi_handle 然后覆盖 - 什么 在测试中)
在成功/失败后删除句柄 curl_ multi_ remove_ handle
将 CURLOPT_CONNECTTIMEOUT 和 CURLOPT_TIMEOUT 设置为无穷大。
使用 Php 版本 5.4.14 对此进行测试 希望我已经充分说明了这些要点。
感谢阅读。
最佳答案
我一直在研究你的脚本一段时间,现在试图让它工作。
只有当我阅读Repeated calls to this function will return a new result each time, until返回一个 FALSE 作为此时没有更多可获取的信号。,对于 http://se2.php.net/manual/en/function.curl-multi-info-read.php ,我意识到 while 循环可能会起作用。
额外的 while 循环使它的行为完全符合您的预期。这是我得到的输出:
http://smotri.com/video/list/sports/ failed
http://smotri.com/video/list/travel/ failed
http://smotri.com/video/list/gaming/ failed
http://smotri.com/video/list/erotic/ failed
http://smotri.com/video/list/humour/ failed
http://smotri.com/video/list/animals/ success
http://smotri.com/video/list/film/ success
http://smotri.com/video/list/auto/ success
http://smotri.com/video/list/ failed
http://smotri.com/video/list/hobby/ failed
http://smotri.com/video/list/mult/ failed
这是我用来测试的代码:
<?php
set_time_limit(0);
$l = array(
'http://smotri.com/video/list/',
'http://smotri.com/video/list/sports/',
'http://smotri.com/video/list/animals/',
'http://smotri.com/video/list/travel/',
'http://smotri.com/video/list/hobby/',
'http://smotri.com/video/list/gaming/',
'http://smotri.com/video/list/mult/',
'http://smotri.com/video/list/erotic/',
'http://smotri.com/video/list/auto/',
'http://smotri.com/video/list/humour/',
'http://smotri.com/video/list/film/'
);
$mh = curl_multi_init();
$s = 0;
$f = 10;
while($s <= $f)
{
$ch = curl_init();
if($s%2)
{
$curlsettings = array(
CURLOPT_URL => $l[$s],
CURLOPT_TIMEOUT_MS => 3000,
CURLOPT_RETURNTRANSFER => 1,
);
}
else
{
$curlsettings = array(
CURLOPT_URL => $l[$s],
CURLOPT_TIMEOUT_MS => 4000,
CURLOPT_RETURNTRANSFER => 1,
);
}
curl_setopt_array($ch, $curlsettings);
curl_multi_add_handle($mh,$ch);
$s++;
}
$active = null;
do
{
$mrc = curl_multi_exec($mh,$active);
curl_multi_select($mh);
while($info = curl_multi_info_read($mh))
{
echo '<pre>';
//var_dump($info);
if($info['result'] === 0)
{
echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' success<br>';
}
else
{
echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' failed<br>';
}
}
} while ($active > 0);
curl_multi_close($mh);
希望对您有所帮助。为了进行测试,只需将 CURLOPT_TIMEOUT_MS 调整为您的互联网连接。我做到了,所以它在 3000 和 4000 毫秒之间交替,因为 3000 会失败,而 4000 通常会成功。
更新
在浏览了 PHP 和 libCurl 文档后,我发现了 curl_multi_exec 的工作原理(在 libCurl 中它的 curl_multi_perform)。第一次被调用时,它开始处理所有添加的句柄(之前通过 curl_multi_add_handle 添加)的传输。
它分配给 $active 的数字是仍在运行的传输数。因此,如果它少于您拥有的句柄总数,那么您就知道一个或多个传输已完成。所以 curl_multi_exec 也充当一种进度指示器。
由于所有传输都以非阻塞方式处理(传输可以同时完成),while 循环 curl_multi_exec 的 in 不能表示已完成的 url 请求的每次迭代。
所有数据都存储在一个队列中,因此一旦一个或多个传输完成,您就可以调用 curl_multi_info_read 来获取这些数据。
在我最初的回答中,我在 while 循环中使用了 curl_multi_info_read。这个循环会一直迭代,直到 curl_multi_info_read 发现队列中没有剩余数据。之后,如果 $active != 0(意味着 curl_multi_exec 报告传输仍未完成),则外部 while 循环将进入下一次迭代。
总而言之,当仍有未完成的传输时,外循环会继续迭代,而只有当传输完成后有数据时,内循环才会迭代。
PHP 文档对于 curl 多功能来说非常糟糕,所以我希望这能解决一些问题。下面是执行相同操作的另一种方法。
do
{
curl_multi_exec($mh,$active);
} while ($active > 0);
// while($info = curl_multi_info_read($mh)) would work also here
for($i = 0; $i <= $f; $i++){
$info = curl_multi_info_read($mh);
if($info['result'] === 0)
{
echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' success<br>';
}
else
{
echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' failed<br>';
}
}
从这些信息中,您还可以看到不需要 curl_multi_select,因为您不希望某些东西在有事件之前阻塞。
使用您在问题中提供的代码,在几次传输失败后似乎 curl 没有继续进行,但实际上缓冲区中仍有数据排队。您的代码没有足够多次调用 curl_multi_info_read。您的代码获取所有成功传输的原因是由于 PHP 在单个线程上运行,因此脚本挂起等待请求。失败请求的超时对 PHP 的影响不足以使其挂起/等待那么长时间,因此 while 循环执行的迭代次数少于排队数据的数量。
关于php - 与 CURL Multi PHP 的不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22539555/
两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
我希望特定模型的所有数据库交互都通过集群中的mongo主节点,因此我将模型设置为使用强一致性。classPhotoincludeMongoid::Documentwithconsistency::strongfield:number,type:Integer#let'ssayaphotonumberisuniqueinthedbvalidate:unique_numberend但这似乎不起作用,因为当我保存两张非常靠近的照片时,我仍然遇到验证错误。photo1#dbhasnumber=1forthisobjectphoto1.update_attributes(number:2)pho
gemspec语义版本控制运算符~>(又名twiddle-wakka,又名pessimistic运算符)允许限制gem版本但允许进行一些升级。我经常看到它可以读作:"~>3.1"=>"Anyversion3.x,butatleast3.1""~>3.1.1"=>"Anyversion3.1.x,butatleast3.1.1"但是有了一个数字,这条规则就失效了:"~>3"=>"Anyversionx,butatleast3"*NOTTRUE!*"~>3"=>"Anyversion3.x"*True.Butwhy?*如果我想要“任何版本3.x”,我可以只使用“~>3.0”,这是一致的。就
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我使用PHP的时间太长了,对它感到厌倦了。我也想学习一门新语言。我一直在使用Ruby并且喜欢它。我必须在Rails和Sinatra之间做出选择,那么您会推荐哪一个?Sinatra真的不能用来构建复杂的应用程序,它只能用于简单的应用程序吗?
我很确定Ruby有这些(等同于__call、__get和__set),否则find_by将如何在Rails中工作?也许有人可以举一个简单的例子来说明如何定义与find_by相同的方法?谢谢 最佳答案 简而言之你可以映射__调用带有参数的method_missing调用__设置为方法名称以'='结尾的method_missing调用__获取不带任何参数的method_missing调用__调用PHPclassMethodTest{publicfunction__call($name,$arguments){echo"Callingob
Lisp是否适合Web编程/应用程序(交互式),就像ruby和php一样?需要考虑的事情是:易于使用可部署性难度(尤其是对于编程初学者而言)(编辑)在阅读PaulGraham'sessay之后,我特别提到了CommonLisp.将是我的第一门编程语言。在这方面。这样做合适吗?我听说Clojure的宏功能不如CommonLisp的强大,这就是我尝试学习Clojure的原因。它教授编程并且非常强大。 最佳答案 Lisp是一个语系,而不是单一的语言。为了稍微回答您的问题,是的,存在用于各种Lisp方言的Web框架,例如用于Common
好的,所以我将我自己的DSL中的一些东西与Ruby进行了比较。他们都支持的一个结构是这个x=["key"=>"value"]知道数组和散列的区别,我会认为这是不合法的,但是在Ruby中的结果是[{"key"=>"value"}]这是为什么?有了这种语法,你为什么不能这样做x=("key"=>"value")为什么数组是隐式创建的哈希的特例? 最佳答案 另一个特殊情况是在函数调用中,考虑:deff(x)puts"OK:#{x.inspect}"endf("foo"=>"bar")=>OK:{"foo"=>"bar"}因此在某些情况下,
我刚刚在编程语言ruby中发现了一个奇怪的问题,这不是什么大问题,但我就是不明白为什么会这样。如果有人知道我的问题的问题,我会很感兴趣。在ruby中你可以写成0或者00,没关系,结果是一样的。如果您运行0===00,您还会得到true,这意味着两个输入完全相同。0.0也等于0,所以逻辑上00.0也应该等于0.0但问题是,如果你尝试使用数字00.0那么你只会得到一个错误。例如,如果您运行:a=00.0你得到这个错误:syntaxerror,unexpectedtINTEGER当然我知道这是个小问题,但如前所述,我想了解为什么计算机不将00.0视为与0.0相同?
项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信校园跑腿小程序系统,前台用户使用小程序发布跑腿任何和接跑腿任务,后台管理使用基于PHP+MySql的B/S架构;通过后台管理跑腿的用户、查看跑腿信息和对应订单。意义:手机网络时代,大学生通过手机网购日常用品、外卖外卖、代取快递等已不再是稀奇的事情。此外,不少高校还流行着校园有偿工作,校园跑腿就成了大学生创业服务项目。 因为你在校园里,所以不会有进入的限制。并不是所有的外卖平台都可以随意进入校园,比如小黄和小蓝的双打外卖平台。许多大学禁止送餐进入学校,更不用说送餐进入宿舍了。这一措施使得校园服务市场的竞争相对不