如何在PHP中正确循环发送分页接口请求
基于下一页链接的分页全量数据拉取实现(PHP cURL)
你原有实现存在4个会导致逻辑异常的问题:
- 首次请求返回的第一页数据没有存入结果数组,会直接丢失首页内容
- cURL初始化、公共请求头配置重复编写两次,代码冗余度高
- 没有任何异常容错逻辑,遇到网络超时、接口返回非JSON内容时,会直接抛出PHP警告甚至进入死循环
- 没有请求频率控制,拉取大页数数据时极易触发接口限流
修正后的可复用实现如下:
function get_all_goods(string $initialUrl, string $token, int $requestIntervalMs = 100): array { $allData = []; $currentUrl = $initialUrl; // 公共请求头配置仅定义一次,全局复用 $headers = [ "accept: application/json;charset=utf-8", "Authorization: Bearer $token", "Content-Type: application/json-patch+json", ]; while (!empty($currentUrl)) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $currentUrl, CURLOPT_HTTPHEADER => $headers, CURLOPT_HEADER => 0, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, // 配置10秒超时避免请求卡死 ]); $resp = curl_exec($curl); $curlErrno = curl_errno($curl); $curlError = curl_error($curl); curl_close($curl); // 请求错误直接抛出异常,终止循环避免无效请求 if ($curlErrno) { throw new \RuntimeException("cURL请求失败: " . $curlError); } $res = json_decode($resp, true); // JSON解析失败抛出异常,避免后续逻辑报错 if (json_last_error() !== JSON_ERROR_NONE) { throw new \RuntimeException("接口返回数据JSON解析失败: " . json_last_error_msg()); } // 存入当前页数据,若需要直接合并商品一维数组,可改为array_push($allData, ...$res['data']),data字段需匹配你接口的实际返回结构 $allData[] = $res; // 更新下一页请求地址,无下一页时置空终止循环 $currentUrl = $res['meta']['nextHref'] ?? ''; // 按配置间隔休眠,避免请求频率过高触发限流 if ($currentUrl && $requestIntervalMs > 0) { usleep($requestIntervalMs * 1000); } } return $allData; }
使用说明
- 调用时直接传入第一页的接口地址、对应鉴权token即可,函数会自动循环拉取直到没有下一页链接
- 默认100ms的请求间隔可根据接口实际限流规则调整,不需要间隔时第三个参数传0即可
- 若接口返回格式有调整,只需要修改对应字段匹配逻辑,不需要改动整体循环结构
内容的提问来源于stack exchange,提问作者TokyoDead
相关产品推荐
相关产品推荐

