0

0

PHP批量调用API写入数据库失败的解决方案:应对请求限流与优化性能

聖光之護

聖光之護

发布时间:2026-02-07 22:10:39

|

692人浏览过

|

来源于php中文网

原创

PHP批量调用API写入数据库失败的解决方案:应对请求限流与优化性能

本文详解php脚本在批量插入多列数据时中途停止(通常20–50条后)的根本原因——api请求频率超限(http 429),并提供延迟控制、错误捕获、sql安全加固及批量更新优化等实用解决方案。

在使用 PHP 批量从外部 API 获取数据并写入 MySQL 数据库时,看似逻辑正确的脚本却频繁在处理第 20–50 条记录时中断,这并非数据库连接或 SQL 语法问题,而极大概率源于上游 API 的速率限制(Rate Limiting)。正如实际调试所揭示的:调用 curl_error($curl) 后明确返回了 {"error":"429 - Too many requests in too short timeframe..."} —— 这是典型的 HTTP 429 Too Many Requests 响应,表明目标 API(如 Statistics Norway 的 SSB API)为防止滥用,对单位时间内的请求数做了严格限制。

? 根本原因分析

  • 原脚本对每个市镇(共约 360 个)发起独立的 cURL POST 请求,无任何节流机制;
  • 每次请求需建立 TCP 连接、传输 JSON 查询体、等待响应、解析 JSON,耗时虽短但累积密集;
  • 多数政府/公共 API(如 SSB、GeoNorge)默认限制为 ~60 次/分钟 或更严,超出即返回 429;
  • 错误未被捕获,curl_exec() 返回 false,后续 $test = json_decode($resp, true) 得到 null,导致 $test['value'][0] 等访问触发 Notice,最终 mysqli_query() 因空值或非法 SQL 报错中断流程。

✅ 推荐解决方案(四步优化)

1. 添加健壮的 cURL 错误与 HTTP 状态检查

$resp = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$curlErr = curl_error($curl);

if ($resp === false || $httpCode !== 200) {
    $errorMsg = "cURL failed for kommune $kommune ({$kommune_navn}): ";
    $errorMsg .= $curlErr ?: "HTTP {$httpCode}";
    error_log($errorMsg); // 记录到日志,避免阻塞页面输出
    echo "⚠️ Skipped $kommune due to API error.
"; curl_close($curl); continue; // 跳过当前市镇,继续下一轮 } curl_close($curl);

2. 实施请求节流(简单有效)

在循环末尾添加 usleep() 实现毫秒级延迟,例如每请求间隔 1–2 秒:

// 在本次更新完成后、下一次循环开始前插入
usleep(1500000); // 1.5 秒,确保远低于 60req/min 限制
? 提示:usleep(1500000) ≈ 1.5 秒,360 条 × 1.5s ≈ 9 分钟完成,安全且可接受。可根据实际限流策略微调(如 usleep(1000000) 对应 60req/min)。

3. 修复 SQL 安全隐患与变量错误

原代码存在两处高危问题:

  • ❌ 使用未转义的变量直接拼接 SQL(易受 SQL 注入);
  • ❌ mysqli_error($conn) 中 $conn 未定义(应为 $tilkobling);

✅ 正确做法:使用预处理语句(Prepared Statements)

立即学习PHP免费学习笔记(深入)”;

UP简历
UP简历

基于AI技术的免费在线简历制作工具

下载
$stmt = $tilkobling->prepare(
    "UPDATE kommuneinfo SET 
        befolkning1970 = ?, befolkning1975 = ?, befolkning1980 = ?,
        befolkning1985 = ?, befolkning1990 = ?, befolkning1995 = ?,
        befolkning2000 = ?, befolkning2005 = ?, befolkning2010 = ?,
        befolkning2015 = ?, befolkning2020 = ?
     WHERE kommunenummer = ?"
);
$stmt->bind_param(
    "iiiiiiiiiii", 
    $befolkning1970, $befolkning1975, $befolkning1980,
    $befolkning1985, $befolkning1990, $befolkning1995,
    $befolkning2000, $befolkning2005, $befolkning2010,
    $befolkning2015, $befolkning2020,
    $kommune
);
if (!$stmt->execute()) {
    error_log("DB update failed for $kommune: " . $stmt->error);
    echo "❌ DB Error for {$kommune_navn} ({$kommune}): " . $stmt->error . "
"; } $stmt->close();

4. (进阶)减少 API 调用次数 —— 探索批量查询可能

查阅 SSB API 文档 可知,其支持在单个请求中查询多个区域(values 数组可包含多个 "K_XXXX")。若市镇列表已知,可尝试分批(如每批 5–10 个市镇)提交,大幅降低总请求数。示例片段:

// 构建 values 数组:["K_0101","K_0102",...,"K_0110"]
$regionValues = array_map(fn($code) => "K_$code", array_slice($allKommuner, $i, 10));
// 替换原 data 中的 "values": ["K_$kommune"] → "values": $regionValues
// 注意:需同步解析返回的多维 value 结构(按 region × year 排列)

此举可将 360 次请求压缩至约 40 次,从根本上规避限流。

? 总结与最佳实践

问题类型 解决方案 优先级
API 429 限流 usleep() 节流 + curl_error() 监控 ⭐⭐⭐⭐⭐
SQL 注入风险 全面改用 mysqli::prepare() + bind_param() ⭐⭐⭐⭐⭐
错误静默失败 error_log() 记录 + continue 跳过异常项 ⭐⭐⭐⭐
性能瓶颈 探索 API 批量查询能力,合并请求 ⭐⭐⭐

✅ 最终建议:先实施 1–3 步(快速见效),稳定运行后再评估第 4 步。同时,将脚本拆分为「获取数据」与「写入数据库」两个阶段,并加入进度持久化(如记录已处理 kommunenummer 到临时表),避免意外中断后全量重跑。

通过以上优化,您的 PHP 数据导入脚本将具备生产环境所需的健壮性、安全性与可维护性,轻松完成数百条记录的可靠写入。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

856

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

331

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

351

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1468

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

365

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1045

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

430

2024.04.29

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

39

2026.02.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.1万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 823人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号