You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP脚本多商品订单拆分问题:合并多商品为单个订单发送至API

问题描述

我写了一段PHP脚本,用来从API获取订单的JSON数据,再把订单通过API发送到另一个系统。流程都正常,但有个问题:当订单包含多个商品时,脚本会给每个商品创建独立订单,而不是把所有商品合并到同一个订单里。

当前代码

foreach($data['orders'] as $key => $val)
{
    $phone = $val['phone'];
    $email = $val['email'];
    $fullname = $val['invoice_fullname'];    
    $invoicecompany = $val['invoice_company'];
    $invoicenip = $val['invoice_nip'];
    $invoiceaddress = $val['invoice_address'];
    $invoicecity = $val['invoice_city'];
    $deliveryprice = $val['delivery_price'];
    $deliverymethod = $val['delivery_method'];
}

foreach($data['orders'][0]['products'] as $key => $val){
    $pidBl = $val['product_id'];
    $ean = $val['ean'];
    $grossprice = $val['price_brutto'];
    $vatrate = $val['tax_rate'];
    $quantity = $val['quantity'];

//open db
$dbc = mysqli_connect ($dbhost, $dbuser, $dbpassword);
$dbSelected = mysqli_select_db($dbc , $database);
$q = $dbc->query("SELECT pId FROM offers WHERE pBarcode = '$ean';");

while ($rs = $q->fetch_assoc()) {
    $pId = $rs['pId'];
}
$arr = [
        "objects" => [],
        "returnColumns" => []
    ];
$arr['objects'][] = [
"name" => $fullname,
"uniqueCode" => $invoicenip,
"active" => "true"
];
$arr['returnColumns'][] = ["name" => "id"];

$preparesedona = json_encode($arr);

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => 'BLABLABLA',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => $preparesedona,
  CURLOPT_HTTPHEADER => array(
    'accept: application/json',
    'Authorization: Basic BLABLABLA',
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);

foreach($data['result'] as $key => $val){
$customerId = $val['id'];
}

$arr = [
        "objects" => [],
        "returnColumns" => []
    ];

$arr['objects'][] = [
"client_id" => $customerId,
"user_id" => 1,
"administration_id" => 1,
"status" => 1,
"deliveryType" => 1,
"details" => []
];

$arr['objects'][0]['details'][] =  [
"product_id" => $pId,
"unitPriceWithVat" => $grossprice,
"orderedUnits" => $quantity
];

$arr['returnColumns'][] = ["name" => "id"];

$preparesedona = json_encode($arr);

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => 'BLABLABLA',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => $preparesedona,
  CURLOPT_HTTPHEADER => array(
    'accept: application/json',
    'Authorization: Basic BLABLABLA',
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);
curl_close($curl);
echo $response;
}

当前输出的POST数据格式

{
   "objects":[{
         "client_id":21947,
         "user_id":1,
         "administration_id":1,
         "status":1,
         "deliveryType":1,
         "details":[{
               "product_id":"11407",
               "unitPriceWithVat":159.7,
               "orderedUnits":1
            }]
      }],
   "returnColumns":[{
         "name":"id"
      }]
}{
   "objects":[{
         "client_id":21948,
         "user_id":1,
         "administration_id":1,
         "status":1,
         "deliveryType":1,
         "details":[{
               "product_id":"14575",
               "unitPriceWithVat":45.31,
               "orderedUnits":1
            }]
      }],
   "returnColumns":[{
         "name":"id"
      }]
}

期望的正确格式

{
   "objects":[{
         "client_id":21947,
         "user_id":1,
         "administration_id":1,
         "status":1,
         "deliveryType":1,
         "details":[{
               "product_id":"11407",
               "unitPriceWithVat":159.7,
               "orderedUnits":1
            },{
               "product_id":"14575",
               "unitPriceWithVat":45.31,
               "orderedUnits":1
            }]
      }],
   "returnColumns":[{
         "name":"id"
      }]
}

我是编程新手,正在学习,希望能得到代码调整的指导。


解决方案

问题核心是你把创建订单、调用API的逻辑放到了商品循环里面,导致每个商品都会触发一次订单创建请求。需要把循环逻辑拆分:先处理客户信息,再批量收集所有商品,最后一次性创建包含所有商品的订单。

调整后的代码如下:

// 先处理订单基本信息(假设$data['orders']里只有一个订单,按原代码逻辑取第一个)
$order = $data['orders'][0];
$phone = $order['phone'];
$email = $order['email'];
$fullname = $order['invoice_fullname'];    
$invoicecompany = $order['invoice_company'];
$invoicenip = $order['invoice_nip'];
$invoiceaddress = $order['invoice_address'];
$invoicecity = $order['invoice_city'];
$deliveryprice = $order['delivery_price'];
$deliverymethod = $order['delivery_method'];

// 第一步:创建客户(仅执行一次,无需循环)
$arr = [
    "objects" => [],
    "returnColumns" => []
];
$arr['objects'][] = [
    "name" => $fullname,
    "uniqueCode" => $invoicenip,
    "active" => "true"
];
$arr['returnColumns'][] = ["name" => "id"];

$preparesedona = json_encode($arr);

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => 'BLABLABLA',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => $preparesedona,
  CURLOPT_HTTPHEADER => array(
    'accept: application/json',
    'Authorization: Basic BLABLABLA',
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);
curl_close($curl);

$data_customer = json_decode($response, true);
$customerId = $data_customer['result'][0]['id']; // 直接取第一个结果的ID,无需循环

// 第二步:批量收集所有商品信息
$orderDetails = [];
// 仅连接一次数据库,避免循环内重复连接
$dbc = mysqli_connect ($dbhost, $dbuser, $dbpassword);
mysqli_select_db($dbc , $database);

foreach($order['products'] as $key => $val){
    $ean = $val['ean'];
    $grossprice = $val['price_brutto'];
    $quantity = $val['quantity'];

    // 查询商品ID
    $q = $dbc->query("SELECT pId FROM offers WHERE pBarcode = '$ean';");
    $rs = $q->fetch_assoc();
    $pId = $rs['pId'];

    // 将商品信息添加到详情数组
    $orderDetails[] = [
        "product_id" => $pId,
        "unitPriceWithVat" => $grossprice,
        "orderedUnits" => $quantity
    ];
}
// 关闭数据库连接
mysqli_close($dbc);

// 第三步:创建包含所有商品的订单(仅执行一次)
$arr_order = [
    "objects" => [],
    "returnColumns" => []
];

$arr_order['objects'][] = [
    "client_id" => $customerId,
    "user_id" => 1,
    "administration_id" => 1,
    "status" => 1,
    "deliveryType" => 1,
    "details" => $orderDetails // 传入批量收集的所有商品
];

$arr_order['returnColumns'][] = ["name" => "id"];

$preparesedona_order = json_encode($arr_order);

$curl_order = curl_init();
curl_setopt_array($curl_order, array(
  CURLOPT_URL => 'BLABLABLA',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => $preparesedona_order,
  CURLOPT_HTTPHEADER => array(
    'accept: application/json',
    'Authorization: Basic BLABLABLA',
    'Content-Type: application/json'
  ),
));

$response_order = curl_exec($curl_order);
curl_close($curl_order);
echo $response_order;

关键调整点说明

  • 客户创建逻辑移到商品循环外:客户信息属于整个订单,只需要创建一次,避免原代码中循环创建客户导致生成多个client_id
  • 批量收集商品详情:先遍历所有商品,将每个商品的信息存入数组,最后一次性传入订单的details字段
  • 优化数据库连接:仅连接一次数据库,避免循环内重复连接浪费资源
  • 简化客户ID获取:直接取API返回结果的第一个元素ID,无需循环遍历

内容的提问来源于stack exchange,提问作者melvinfree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:40:31