php - 从 localhost 到实时站点的 Curl 响应不一致
问题描述
大家好,我有一个 php 文件,它返回我从 curl 的响应构造的 JSON。我的问题是当我在本地(本地主机)服务器中运行它时,JSON 响应的长度是 55,这是正确的,它得到了我需要的所有事件。但是当我在我们的托管站点上尝试时,响应不一致,它与本地主机不同。对于第一次加载,我检查了长度响应,它返回 55 个事件中的 32 个事件,然后我尝试再次重新加载它,然后响应增加到 39 等等。
这是我的本地主机响应。[ https://prnt.sc/rll4w0]。这是托管在 cpanel https://cdev.trilogycap.co/icedev/dynamic/civicore.php上的文件。这是第一个响应https://prnt.sc/rll2rc。当我再次重新加载此页面时https:// prnt.sc/rll3fl
我的php文件函数流程是这样的。我有一个函数可以获取今年事件的所有 ID 并将其推送到全局数组。我已经删除了那里的重复 ID。所以现在我为 multicurl 调用一个函数。
其中,对于每个 ID,我将再次处理和调用 API 并构建它。然后我将它推送到全局的 responseEvents 变量数组中,然后我对其进行编码以生成有效的 JSON 文件。我在多卷曲中是否有连接或错误的事情?它们是 php multi curl 的执行限制吗?还是 settimelimit(0) 会影响我的代码?
这是我的代码
<?php
//Use this so that when we run the curl it wont timeout when dealing with getting data
set_time_limit(0);
$API_KEY = "APIKEY";
$CURRENT_YEAR = date("Y");
$CURRENT_MONTH = date("m");
$CURRENT_DAY = date("d");
$events = getOpportunityYearly();//array of ID's removed duplicates [1,1,2,3,4,5 etc]
$noDuplicate = array_values(array_unique($events));//remove $event ID duplciates
$responseEvents = [];//this is the array to be returned as json to use
//pass noDuplicate array which holds event ID's
multiCurl($noDuplicate);
print_r(json_encode($responseEvents, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP |JSON_UNESCAPED_SLASHES ));
//returns an array of ID of events
function getOpportunityYearly(){
$eventArr = [];//pass eventsID here
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.com/voc/api/v3/data/opportunities_dates?key='.$GLOBALS['API_KEY'].'&fields=["startDate","endDate","opportunities_id"]&where={"whereType":"AND","clauses":[{"fieldName":"startDate","operator":">=","operand":"'.$GLOBALS['CURRENT_YEAR'].'-'.$GLOBALS['CURRENT_MONTH'].'-'.$GLOBALS['CURRENT_DAY'].'"},{"fieldName":"endDate","operator":"<=","operand":"'.$GLOBALS['CURRENT_YEAR'].'-12-31"}]}',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
));
//convert response to obj
$response = json_decode(curl_exec($curl));
curl_close($curl);
$eventsID = $response->records;
//print_r($eventsID);
//every opportunity object get its id and push to events array
foreach($eventsID as $opportunity){
array_push($eventArr,$opportunity->opportunities_id->value);
}
return $eventArr;
}
function multiCurl($eventArray){
// array of curl handles
$multiCurl = array();
// data to be returned
$result = array();
// multi handle
$mh = curl_multi_init();
$index = null;
foreach ($eventArray as $event) {
//$event are the ID per each event
$multiCurl[$event] = curl_init();
curl_setopt_array($multiCurl[$event], array(
CURLOPT_URL =>'https://api.com/voc/api/v3/data/opportunities/'.$event.'?key='.$GLOBALS['API_KEY'].'&fields=["opportunityName","typeOfWork","firstDateInOpportunity","lastDateInOpportunity","startTime","endTime","physicalDifficulty","minimumAge","location","state","city","county","campingAvailable","groupsAllowed","registrationFormID","cRQ_payment","paymentAmount","additionalInformation","photo","displayToPublic","latitude","longitude","summary","description","photo"]&where={"whereType":"AND","clauses":[{"fieldName":"displayToPublic","operator":"checked"}]}',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET"
));
curl_multi_add_handle($mh, $multiCurl[$event]);
}
do {
curl_multi_exec($mh,$index);
} while($index > 0);
// get content and remove handles
foreach($multiCurl as $key=>$value) {
$records = json_decode(curl_multi_getcontent($value));//response of each request
$record = $records->records[0];
if(strtolower($record->displayToPublic->displayValue) == 'yes'){
$eve = [
"page_item_url"=> $record->opportunities_id->value,
"data"=>[
"typeOfWork"=>$record->typeOfWork->displayValue,
"opportunityName"=> $record->opportunityName->displayValue,
"firstDateInOpportunity"=> $record->firstDateInOpportunity->displayValue,
"lastDateInOpportunity"=> property_exists($record, 'lastDateInOpportunity') ? $record->lastDateInOpportunity->displayValue : $record->firstDateInOpportunity->displayValue,
"startTime"=>$record->startTime->displayValue,
"endTime"=>$record->endTime->displayValue,
"physicalDifficulty"=>$record->physicalDifficulty->displayValue,
"minimumAge"=>$record->minimumAge->displayValue,
"location"=>$record->location->displayValue,
"state"=>$record->state->displayValue,
"city"=>$record->city->displayValue,
"county"=>$record->county->displayValue,
"campingAvailable"=>$record->campingAvailable->displayValue,
"groupsAllowed"=>$record->groupsAllowed->displayValue,
"registrationFormID"=>$record->registrationFormID->displayValue,
"cRQ_payment"=>$record->cRQ_payment->displayValue,
"paymentAmount"=>$record->paymentAmount->displayValue,
"photo"=>$record->photo->displayValue,
"displayToPublic"=>$record->displayToPublic->displayValue,
"latitude"=> property_exists($record, 'latitude') ? $record->latitude->displayValue : "0",
"longitude"=> property_exists($record, 'longitude') ? $record->longitude->displayValue : "0",
"photo"=>$record->photo->displayValue,
"description"=> $record->description->displayValue,
"additionalInformation"=> $record->additionalInformation->displayValue,
"summary"=> $record->summary->displayValue
]
];
array_push($GLOBALS["responseEvents"],$eve);
curl_multi_remove_handle($mh, $value);
}
}//foreach
curl_multi_close($mh);
}
?>
解决方案
我认为不知何故,您的 curl 在输入此 foreach 时并未检索到所有信息,foreach($multiCurl as $key=>$value)
这可以解释为什么在本地(快速响应)而不是在您的远程服务器(网络时间,更长的响应时间)上可以。
你应该试试这个,我从文档中得到,应该等待所有连接正确结束。
do {
$status = curl_multi_exec($mh, $index);
if ($index) {
// Wait a short time for more activity
curl_multi_select($mh);
}
} while ($index && $status == CURLM_OK);
推荐阅读
- asp.net - 当多个 Blazor 应用发布到 IIS 时,我们收到 HTTP 错误 500.35 - ASP.NET Core 不支持同一应用池中的多个应用
- java - 检查过滤后的列表是否为空(不为空)
- django - “错误:错误解码签名”和“变量 '$token' 从未在操作 'VerifyToken' 中使用。”
- django - Heroku 日志排水(流)指南
- c++ - 如何用 boost qi 解析 rtsp url?
- spring-boot - 实现文件选择器 (GUI) 以在 Spring Boot Web App 中向电子邮件添加附件
- c++ - 用多个空格替换字符串中的制表符
- swift - 未找到用于应用扩展的 iOS cocoapod 框架 (IJKMediaFrameworkWithSSL)
- .net-core - 在 Efcore 中包含子过滤器未按预期工作
- windows - 由于文件路径错误,Git 克隆无法正常工作