如何访问嵌套JSON数据并修正PHP代码中的静态产品ID问题?
问题:无法正确访问嵌套JSON数据以更新数据库spID和svID
需求是从数据库获取bpID,调用接口获取对应产品数据,更新数据库的spID和svID,但目前无法正确访问嵌套JSON数据,需解决静态产品ID的匹配问题。
返回的JSON数据结构
{"status":"SUCCESS","products":{"6605995":{"is_bundle":false,"ean":"5949234930002","sku":"KNK-BAN-MP","tax_rate":19,"weight":0,"height":0,"width":0,"length":0,"star":0,"category_id":647123,"manufacturer_id":174472,"text_fields":{"name":"Bandaje Box Knockout Balcescu"},"stock":{"bl_11206":79},"prices":{"10929":69},"locations":{"bl_11206":""},"links":{"shop_4000268":{"product_id":"6665093873699","variant_id":"0"}},"average_cost":0,"average_landed_cost":0,"images":{"1":"https://cdn.shopify.com/s/files/1/0273/9034/5251/products/image.jpg?v=1657567836","2":"https://cdn.shopify.com/s/files/1/0273/9034/5251/products/image_37af2a9f-83c9-4a1f-84d6-3ad0e6aa62a3.jpg?v=1657567836"}}}}
当前PHP代码
$arr = [ 'inventory_id' => $inventoryid, 'products' => [] ]; $q = $dbc->query("SELECT bpID FROM Products LIMIT 3"); while($row = mysqli_fetch_assoc($q)) { $bpID = $row['bpID']; $arr['products'][] = $row['bpID']; } $getproductidsp = [ 'method' => 'getInventoryProductsData', 'parameters' => json_encode($arr), ]; $ch = curl_init(); $output = curl_exec($ch); $data = json_decode($output, true); var_dump($data); foreach($data['products'][$bpID]['links'] as $key => $val){ $prod = $val['product_id']; $variant = $val['variant_id']; $query = "UPDATE IGNORE Products SET spID='$prod', svID='$variant' WHERE bpID='$bpID';"; $result = mysqli_query ($dbc, $query) or die (mysqli_error($dbc)); echo $result; mysqli_close($dbc);
问题分析与解决方案
核心问题
- 变量作用域失效:
$bpID仅保留while循环最后一条记录的值,无法对应所有从数据库取出的bpID。 - JSON访问逻辑错误:接口返回的
products是以bpID为键的关联数组,需遍历所有返回的产品,而非直接使用循环外的$bpID。 - CURL配置缺失:
curl_init()未设置请求地址、请求方式等必要参数,导致请求失败无法获取数据。 - SQL注入风险:直接拼接变量到SQL语句存在安全隐患。
- 提前关闭数据库连接:循环内调用
mysqli_close($dbc)会导致后续循环无法执行SQL。
修改后的代码
$arr = [ 'inventory_id' => $inventoryid, 'products' => [] ]; // 收集所有bpID,用于后续匹配验证 $bpIDs = []; $q = $dbc->query("SELECT bpID FROM Products LIMIT 3"); while($row = mysqli_fetch_assoc($q)) { $bpID = $row['bpID']; $arr['products'][] = $bpID; $bpIDs[] = $bpID; } // 补充完整CURL配置(替换为实际接口地址) $getproductidsp = [ 'method' => 'getInventoryProductsData', 'parameters' => json_encode($arr), ]; $ch = curl_init('https://your-api-domain.com'); // 替换为实际接口地址 curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($getproductidsp)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json' ]); $output = curl_exec($ch); $curlError = curl_error($ch); curl_close($ch); if($output === false) { die('CURL请求失败: ' . $curlError); } $data = json_decode($output, true); // 验证接口返回状态 if($data['status'] !== 'SUCCESS') { die('接口返回失败'); } // 遍历返回的所有产品,键即为对应bpID foreach($data['products'] as $bpID => $product) { // 可选:过滤非目标bpID的产品 if(!in_array($bpID, $bpIDs)) { continue; } // 处理每个店铺的链接数据 foreach($product['links'] as $shop => $linkInfo) { $prod = $linkInfo['product_id']; $variant = $linkInfo['variant_id']; // 使用预处理语句防止SQL注入 $stmt = $dbc->prepare("UPDATE IGNORE Products SET spID=?, svID=? WHERE bpID=?"); $stmt->bind_param("sss", $prod, $variant, $bpID); $stmt->execute(); echo $stmt->affected_rows > 0 ? "bpID {$bpID} 更新成功<br>" : "bpID {$bpID} 无更新<br>"; $stmt->close(); } } // 所有操作完成后关闭数据库连接 mysqli_close($dbc);
关键改进点
- 收集所有请求的bpID,可过滤接口返回的无关产品。
- 补充完整CURL配置,确保能正确调用接口获取数据。
- 遍历
data['products']的键值对,直接通过键获取对应bpID,完美匹配数据库记录。 - 使用MySQLi预处理语句,彻底避免SQL注入风险。
- 将数据库连接关闭移至所有循环结束后,确保所有更新操作执行完成。
内容的提问来源于stack exchange,提问作者melvinfree
相关产品推荐
相关产品推荐

