登录
首页 >  文章 >  php教程

PHP遍历JSON数据存入数据库方法

时间:2026-06-01 11:06:48 104浏览 收藏

本文深入讲解了在 PHP 中如何安全高效地解析第三方发票 API 返回的 JSON 数据,并通过 foreach 循环精准提取关键字段,再借助 PDO 预处理语句批量写入 MySQL 数据库——不仅彻底规避了因误将原始 JSON 字符串当对象访问(如 $resp->data)导致的常见运行时错误,还系统解决了类型转换、空值防御、SQL 注入防护、重复数据处理及异常日志等实战痛点,为开发者提供了一套开箱即用、健壮可靠的 JSON 数据落地解决方案。

如何在 PHP 中遍历 JSON 数据并批量存入数据库

本文详解如何正确解析 API 返回的 JSON 发票数据,使用 foreach 循环提取关键字段,并安全写入 MySQL 数据库,同时规避常见类型错误与 SQL 注入风险。

本文详解如何正确解析 API 返回的 JSON 发票数据,使用 foreach 循环提取关键字段,并安全写入 MySQL 数据库,同时规避常见类型错误与 SQL 注入风险。

在 PHP 开发中,对接第三方发票 API(如 Fakturoid)后获取 JSON 格式数据是常见场景。但初学者常因混淆 json_decode() 的返回类型(对象 vs 关联数组)导致“Trying to get property 'data' of non-object”等错误——正如问题中 $resp->data 的误用:$resp 是字符串而非对象,且原始 JSON 是顶层数组,没有 .data 属性

✅ 正确解析 JSON:对象模式优先(推荐)

API 返回的是标准 JSON 数组(以 [ {...}, {...} ] 开头),调用 json_decode($json_string) 默认返回 stdClass 对象数组,应直接通过箭头语法访问属性:

$data = json_decode($resp); // 注意:不加 true 参数 → 返回对象数组
if (json_last_error() !== JSON_ERROR_NONE) {
    throw new Exception('JSON 解析失败: ' . json_last_error_msg());
}

foreach ($data as $invoice) {
    $invoice_id     = $invoice->id;
    $invoice_number = $invoice->number;
    $status         = $invoice->status;
    $total          = (float)$invoice->total;
    $issued_on      = $invoice->issued_on;
    $due_on         = $invoice->due_on;
    $client_name    = $invoice->client_name;

    // 示例:打印结构化信息
    echo "发票 #{$invoice_number} (ID: {$invoice_id}) - 状态: {$status}, 金额: {$total} {$invoice->currency}\n";
}

⚠️ 关键纠正:$resp 是 curl_exec() 返回的纯字符串,不是对象,因此 $resp->data 必然报错;json_decode($resp) 后才得到可遍历的数据结构。

?️ 批量写入数据库(MySQL + PDO 预处理)

为保障数据安全与性能,推荐使用 PDO 预处理语句批量插入。假设已创建如下表结构:

CREATE TABLE invoices (
    id BIGINT PRIMARY KEY,
    number VARCHAR(50),
    status VARCHAR(20),
    total DECIMAL(12,2),
    issued_on DATE,
    due_on DATE,
    client_name VARCHAR(255),
    currency CHAR(3),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

完整入库逻辑如下:

try {
    $pdo = new PDO("mysql:host=localhost;dbname=your_db;charset=utf8mb4", $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    ]);

    $stmt = $pdo->prepare(
        "INSERT INTO invoices (id, number, status, total, issued_on, due_on, client_name, currency) 
         VALUES (?, ?, ?, ?, ?, ?, ?, ?)
         ON DUPLICATE KEY UPDATE 
             status = VALUES(status), 
             total = VALUES(total), 
             due_on = VALUES(due_on)"
    );

    $data = json_decode($resp);
    if (!is_array($data)) {
        throw new Exception('JSON 解析结果非数组,请检查 API 响应格式');
    }

    foreach ($data as $invoice) {
        $stmt->execute([
            $invoice->id,
            $invoice->number ?? '',
            $invoice->status ?? 'unknown',
            (float)($invoice->total ?? 0),
            $invoice->issued_on ?? null,
            $invoice->due_on ?? null,
            $invoice->client_name ?? '',
            $invoice->currency ?? 'CZK'
        ]);
    }

    echo "✅ 成功导入 " . count($data) . " 条发票记录";

} catch (PDOException $e) {
    error_log("数据库错误: " . $e->getMessage());
    echo "❌ 数据库操作失败,请查看日志";
} catch (Exception $e) {
    echo "❌ 错误: " . $e->getMessage();
}

? 进阶建议与注意事项

  • 空值防御:所有字段访问均使用 ?? 提供默认值,避免 Undefined property 警告;
  • 类型强转:金额字段强制 (float) 转换,防止字符串参与计算;
  • 事务支持:若需原子性,可在 foreach 前调用 $pdo->beginTransaction(),成功后 commit(),失败则 rollback();
  • 分页处理:真实场景中 API 可能分页返回,需循环请求 ?page=1, ?page=2 并合并数据;
  • Bootstrap 表格渲染(简例):
    echo '<table class="table table-striped"><thead><tr><th>ID</th><th>编号</th><th>状态</th><th>金额</th></tr></thead><tbody>';
    foreach ($data as $inv) {
        echo "<tr><td>{$inv->id}</td><td>{$inv->number}</td><td>{$inv->status}</td><td>{$inv->total} {$inv->currency}</td></tr>";
    }
    echo '</tbody></table>';

掌握 json_decode() 的返回类型差异、善用预处理语句、并添加健壮的异常处理,即可高效、安全地完成 JSON 数据的解析与持久化。

今天带大家了解了的相关知识,希望对你有所帮助;关于文章的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>