PHP脚本调用API仅处理前10条数据问题排查求助
我编写了一段PHP脚本,用来读取JSON文件并将其中的记录作为参数调用API。JSON文件里共有61条记录,但脚本总是在完成第10次API调用后就停止了,只有前10条记录被处理。
脚本代码如下:
function apipost($post_data) { $url = "https://example.com/api/"; $options = array( CURLOPT_URL => $url, CURLOPT_HEADER => true, CURLOPT_VERBOSE => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => false, // for https //CURLOPT_USERPWD => $loginusername . ":" . $loginpassword, //CURLOPT_HTTPAUTH => CURLAUTH_DIGEST, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($post_data) , ); $ch = curl_init(); curl_setopt_array( $ch, $options ); try { $raw_response = curl_exec( $ch ); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($raw_response, 0, $headerSize); $body = substr($raw_response, $headerSize); if(curl_errno($ch)) { return; } $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($status_code != 200) { return; } } catch(Exception $ex) { if ($ch != null) curl_close($ch); { return; } } if ($ch != null) { curl_close($ch); } } $path = 'access_post.json'; $jsonString = file_get_contents($path); $jsonData = json_decode($jsonString, true); if (ob_get_level() == 0) ob_start(); foreach($jsonData['data'] as $post_data) { ob_flush(); flush(); $post_new_data = array( 'state' => $post_data['state'], 'cmd' => $post_data['cmd'], 'card_id' => $post_data['cardid'], 'timestamp' => $post_data['timestamp'] ); printf("%s<br>", json_encode($post_new_data)); apipost($post_new_data); ob_flush(); flush(); }
其中apipost()函数负责配置cURL并调用外部API,该API和脚本部署在同一网站上。想请教这个问题是PHP脚本缺陷导致,还是服务器资源限制引发?
分析与解决方案
一、脚本层面的可能缺陷及修复
错误静默中断:当前
apipost()函数在curl出错、HTTP状态码非200时直接return,没有任何日志或输出,一旦第11次请求出现错误,脚本会静默停止处理后续记录。
修复:在return前添加错误输出与日志:if(curl_errno($ch)) { $err_msg = "CURL错误: " . curl_error($ch); error_log($err_msg); printf("%s<br>", $err_msg); return; } if ($status_code != 200) { $err_msg = "HTTP状态码异常: " . $status_code . ",响应内容: " . $body; error_log($err_msg); printf("HTTP状态码异常: %s<br>", $status_code); return; }同时修正catch块的语法错误(多余大括号):
catch(Exception $ex) { if ($ch != null) curl_close($ch); $err_msg = "异常错误: " . $ex->getMessage(); error_log($err_msg); printf("%s<br>", $err_msg); return; }缺少必要请求头:发送JSON数据时未设置
Content-Type: application/json,部分API会因无法识别请求格式返回非200状态码,导致脚本提前终止。
修复:在curl选项数组中添加:CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', 'Content-Length: ' . strlen(json_encode($post_data)) ),
二、服务器层面的可能限制及排查
PHP执行时间限制:若每次API调用耗时较长,10次调用后可能触发
max_execution_time(默认通常30秒),导致脚本被强制终止。
排查:在脚本开头添加echo ini_get('max_execution_time');查看当前限制,或临时设置set_time_limit(0);取消时间限制测试。服务器连接/请求频率限制:由于API与脚本同服务器,短时间内频繁请求可能触发服务器连接数限制(如Apache的
MaxClients、Nginx的worker_connections)或安全策略的请求频率拦截。
排查:查看服务器日志(Apache error.log、Nginx error.log)是否有连接拒绝、资源耗尽报错;在每次API调用后添加sleep(1);降低请求频率,测试是否能完成所有61次调用。
三、快速验证步骤
- 添加详细错误输出后重新运行脚本,查看第11次请求是否有明确错误提示。
- 手动用第11条记录的参数调用API,确认API本身能否正常处理该数据。
- 临时取消PHP执行时间限制,测试是否能完成全部调用。
内容的提问来源于stack exchange,提问作者Kelvin

