我有一个可以执行以下操作的工作函数。
1。)从网页请求项目列表。 2.)循环获取项目列表并组装一个包含列表中每个项目信息的数组。
循环的当前结构如下:
foreach($list as $key=>$value) {
$url = 'http://www.example.com?item_number=' . $value;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
if(curl_exec($ch) === false){
curl_close($ch);
unset($ch);
} else{
$response = curl_exec($ch);
curl_close($ch);
unset($ch);
$item_details[] = $response;
unset($response);
}
}
我遇到的问题是这个列表可以包含数百个项目。每个项目都对示例站点发出独立请求。这会通过mod_fcgid中的FcgidIOTimeout超出我的脚本。此设置似乎设置为120秒。
我使用godaddy共享主机帐户从cron管理器运行此脚本。我没有能力通过任何ini_set()函数或通过htaccess更改FcgidIOTimeout设置。我的max_execution_time和max_input时间设置远高于120秒。
通过循环延长运行时间,set_time_limit()似乎无法正常工作。
这是我从服务器错误日志中收到的错误。
[warn] [client ] mod_fcgid: read data timeout in 120 seconds
[error] [client ] Premature end of script headers:
我的主要问题是: 1.这样做是为了通过单个请求最小化到示例服务器的握手次数。 2.我是否可以强制脚本延迟标头或强制发送标头以避免错误。
我已经读过我可以使用控制台脚本在shell中运行它,这可能会解决问题,但我会诚实地说我不知道如何创建或触发控制台脚本运行此代码。
提前谢谢。
----我的解决方案---------
我在php文档中找到了curl_multi_exec。我把他们的例子变成了一个函数,你传递了一个url数组以及你想要操作多少个线程。我相信你也可以将curl_opts作为数组传递。知识比我更多的人甚至可以为它写一个课程,但这是我的结果。它确实在20秒内执行我的任务,而在120秒时执行。感谢您的反馈。
此致
function multi_thread_curl($url_array, $number_threads) {
$curl_array = array_chunk($url_array, $number_threads, $preserve_keys = true);
//Iterate through each batch of urls.
foreach($curl_array as $threads) {
//Create your cURL resources.
foreach($threads as $key=>$value) {
${ch . $key} = curl_init();
curl_setopt(${ch . $key}, CURLOPT_URL, $value);
curl_setopt(${ch . $key}, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt(${ch . $key}, CURLOPT_RETURNTRANSFER, true);
curl_setopt(${ch . $key}, CURLOPT_TIMEOUT, 10);
}
//Create the multiple cURL handler.
$mh = curl_multi_init();
//Add the handles.
foreach($threads as $key=>$value) {
curl_multi_add_handle($mh, ${ch . $key});
}
$active = null;
//execute the handles.
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
//Get your data and close the handles.
foreach($threads as $key=>$value) {
$results[$key] = curl_multi_getcontent(${ch . $key});
curl_multi_remove_handle($mh, ${ch . $key});
}
//Close the multi handle exec.
curl_multi_close($mh);
}
return $results;
unset($results);
}