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
相关产品推荐
相关产品推荐

