我有这个功能:
public function syncTerritoriesSOQLQuery($veevaToken, $instanceUrl, $tokenUrl)
{
$soqlQuery2 = "SELECT Id,Name,LastModifiedDate FROM Territory";
$soqlUrl2 = $instanceUrl.'/services/data/v28.0/query/?q='.urlencode($soqlQuery2);
$curl = curl_init($soqlUrl2);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: OAuth $veevaToken"));
$jsonResponse = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status !== 200) {
$respObj['error'] = "Error: call to token URL $tokenUrl failed with status $status, response $jsonResponse, curl_error ".curl_error(
$curl
).", curl_errno ".curl_errno($curl);
return $respObj;
}
curl_close($curl);
$soqlObj2 = json_decode($jsonResponse, true);
return $soqlObj2;
}
当我打电话给我时,我收到了回复:
{
"totalSize": 6911,
"done": false,
"nextRecordsUrl": "/services/data/v28.0/query/01g8000002eI8dMAAS-2000",
"records": [ ... ]
}
这意味着完整的记录集将包含6911个项目,但在第一个请求时,只有前2000个记录才会返回,因为它是分页的。所以我需要一次又一次地调用相同的代码直到"done": true
。在每个新请求中,我需要通过在每次调用时附加值返回来更改$soqlUrl2
。例如:
1st time:
$soqlUrl2 = $instanceUrl.'/services/data/v28.0/query/?q='.urlencode($soqlQuery2);
2nd time:
$soqlUrl2 = $instanceUrl."/services/data/v28.0/query/01g8000002eI8dMAAS-2000";
3rd time:
$soqlUrl2 = $instanceUrl."/services/data/v28.0/query/01g8000002eI8dMAAS-4000";
...
直到done
获得true
回复。我还应该将每次迭代的整个JSON结果合并成一个大的,让我们说:第二次的结果应该与第一次调用的结果合并意味着$soqlObj2
来自3d时间的结果应该与之前的伪合并-code:
merge($soqlObj2, 1st, 2nd, 3rd, ...)
我一直在研究这个功能:
public function performPaginateSOQLQuery($veevaToken, $instanceUrl, $tokenUrl, $nextRecordsUrl, &$dataToSave = array()) {
if ($nextRecordsUrl !== null && $nextRecordsUrl !== "") {
$keepRequesting = true;
while($keepRequesting){
$nextRecordsUrlSOQLQuery = $instanceUrl.$nextRecordsUrl;
$curl = curl_init($nextRecordsUrlSOQLQuery);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: OAuth $veevaToken"));
$jsonResponse = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status != 200) {
$respObj['error'] = "Error: call to token URL $tokenUrl failed with status $status, response $jsonResponse, curl_error ".curl_error(
$curl
).", curl_errno ".curl_errno($curl);
return $respObj;
}
curl_close($curl);
$nextRecordsUrlObj = json_decode($jsonResponse, true);
$dataToSave[] = $nextRecordsUrlObj;
echo "iteration 2", "\n";
echo "url: ", $nextRecordsUrl, "\n";
echo "done: ";
var_dump($nextRecordsUrlObj['done']);
echo "\n";
if($nextRecordsUrlObj['done'] === true) {
$keepRequesting = false;
}
}
return array('url' => $nextRecordsUrlObj, 'data' => $dataToSave);
}
}
我从syncTerritoriesSOQLQuery()
上面的函数中调用它,如下所示:
$entireSoqlObj2 = $this->performPaginateSOQLQuery(
$veevaToken,
$instanceUrl,
$tokenUrl,
$soqlObj2['nextRecordsUrl']
);
但是因为我得到了这个结果所以它不起作用:
iteration 0
url: /services/data/v28.0/query/01g8000002eYb8LAAS-2000
done: bool(false)
iteration 2
url: /services/data/v28.0/query/01g8000002eYb8LAAS-2000
done: bool(false)
iteration 2
url: /services/data/v28.0/query/01g8000002eYb8LAAS-2000
done: bool(false)
iteration 2
url: /services/data/v28.0/query/01g8000002eYb8LAAS-2000
done: bool(false)
iteration 2
url: /services/data/v28.0/query/01g8000002eYb8LAAS-2000
done: bool(false)
正确的输出应该是:
// 1st
url: /services/data/v28.0/query/01g8000002eYb8LAAS-2000
done: bool(false)
// 2st
url: /services/data/v28.0/query/01g8000002eYb8LAAS-4000
done: bool(false)
// 3rd
url: /services/data/v28.0/query/01g8000002eYb8LAAS-6000
done: bool(true)
因为totalSize
是6911,有什么可以帮我修复我的代码吗?我的错误在哪里?
注意:我今天早些时候问this,但我根本不清楚,所以我打开了一个包含更多信息的新问题。
答案 0 :(得分:1)
您的递归函数中应该有context.Background()
,每次都应该使用$soqlObj2['nextRecordsUrl']
进行更新。现在它只是检查第一页,因此你得到第二页的网址。
此外,我不明白为什么你在$nextRecordsUrl
中有这么多代码,你只想迭代performPaginateSOQLQuery()
直到syncTerritoriesSOQLQuery()
,对吧?
<强>更新强>
更新done
以循环显示所有页面。在我做出更改的地方添加了评论。希望有所帮助。
syncTerritoriesSOQLQuery()