
本文详解如何通过 php 的 curl 发起 http 请求,获取 json 格式的 api 响应,并安全、完整地提取嵌套数组中的多条记录(如食物名称、热量、糖分等字段),避免常见解码与遍历误区。
本文详解如何通过 php 的 curl 发起 http 请求,获取 json 格式的 api 响应,并安全、完整地提取嵌套数组中的多条记录(如食物名称、热量、糖分等字段),避免常见解码与遍历误区。
在实际开发中,调用外部营养数据 API(如示例中的食物信息接口)是常见需求。API 返回标准 JSON 结构,但若未正确处理响应体、JSON 解码方式或循环逻辑,极易导致只获取首条数据、键名访问失败或 null 值异常。以下为完整、健壮的实现方案。
✅ 正确流程:cURL 请求 → JSON 解析 → 多项遍历
首先,使用 curl_init() 构建请求,确保启用 CURLOPT_RETURNTRANSFER 以捕获响应体而非直接输出:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/foods'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
⚠️ 注意:务必检查 $response 是否为非空字符串,且 $httpCode === 200,避免对错误响应(如 404、500 或空响应)执行 json_decode()。
接着,安全解码 JSON 并验证结构:
基于三引擎设计,从微信文章、新闻和博客网页提取干净内容,支持标题作者日期元数据,多格式和批量处理。
立即学习“PHP免费学习笔记(深入)”;
if ($response === false || $httpCode !== 200) {
throw new RuntimeException("API request failed: HTTP {$httpCode}");
}
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Invalid JSON response: ' . json_last_error_msg());
}
if (!isset($data['items']) || !is_array($data['items'])) {
throw new RuntimeException("Expected 'items' array not found in response");
}最后,遍历所有 items 并提取所需字段。您之前的代码逻辑正确,但变量每次循环被覆盖,因此仅保留最后一次值。如需收集全部数据,推荐使用数组累积或逐条处理(如存入数据库):
$foods = [];
foreach ($data['items'] as $item) {
// 验证关键字段是否存在,避免 Notice 错误
$foods[] = [
'name' => $item['name'] ?? 'Unknown',
'calories' => (float)($item['calories'] ?? 0),
'sugar_g' => (float)($item['sugar_g'] ?? 0),
'serving_size_g' => (float)($item['serving_size_g'] ?? 0),
'protein_g' => (float)($item['protein_g'] ?? 0),
];
}
// 示例:打印全部食物名称与热量
foreach ($foods as $food) {
echo "{$food['name']}: {$food['calories']} kcal\n";
}? 关键要点总结
- ✅ 使用 json_decode($json, true) 得到关联数组,必须用方括号 [] 访问键(如 $item['name']),不可用对象箭头 ->;
- ✅ foreach 是遍历多条记录的唯一可靠方式——单次赋值(如 $name = $item['name'])会覆盖前值,务必用数组追加($foods[] = [...])或立即处理;
- ✅ 始终校验 json_last_error() 和响应结构(如 isset($data['items'])),生产环境严禁忽略错误;
- ✅ 对数值字段使用 (float) 或 (int) 强制类型转换,避免后续计算异常;
- ✅ 如需更高可靠性,可结合 filter_var() 或专用库(如 league/json-guard)做 Schema 验证。
掌握此模式后,您即可稳定对接任意返回 {"items":[{...},{...}]} 结构的 RESTful API,高效提取结构化数据用于展示、分析或持久化。


















