PHP/MariaDB 使用嵌套 JSON 数组进行重复键更新

Posted

技术标签:

【中文标题】PHP/MariaDB 使用嵌套 JSON 数组进行重复键更新【英文标题】:PHP/MariaDB On Duplicate Key Update with nested JSON array 【发布时间】:2021-10-13 12:13:38 【问题描述】:

所以这个很有趣。我正在将第 3 方 POS 集成到我前段时间为该客户制作的自定义库存管理软件中。 我的系统是基本的 php/html/JS 背景。 我有来自第 3 方系统的 webhook,向我的网站发送有关产品信息和库存详细信息的 JSON 信息。 我遇到的问题是,当我们在 3rd 方系统中更新产品时,我需要将准备好的 INSERT 语句设置为 UPDATE ON DUPLICATE KEY。需要检查的 KEY 是数据库中的第 3 列,是表中唯一的 Unique Key。 主键是另一个 ID,不是由 3rd 方系统提供的。 我似乎无法在我的一生中正确地“构建”这个 ON DUPLICATE KEY UPDATE 功能。

这里有一些代码可以让事情变得有意义: 产品信息来自 hook.php,其中包含以下内容:

HOOK.php
<?php 
header('Content-Type: application/json'); 
$request3 = file_get_contents('php://input'); 
req_dump1 = print_r( $request3, true ); 
fp = file_put_contents( 'req.json', $req_dump1 ); 
?>

这给了我以下 JSON:


  "Id": 8919892,
  "Name": "Final",
  "Description": "Final",
  "CostPrice": 0.95000,
  "SalePrice": 756.00000,
  "CategoryId": 278333,
  "Barcode": "2020202020",
   "BrandId": 151102,
  "SupplierId": 44815,
  "OrderCode": "LKJ-8376594",
   "ProductType": 0,
  "TareWeight": null,
  "ArticleCode": "44-jhaqerkhu",
   "Supplier": 
    "Id": 44815,
    "Name": "House",
    "Description": "House",
   ,
  

然后其余的股票信息来自 Stock Detail(为什么他们[3rd party] 将它分开 IDK,我没有构建它)它点击 hook4.php:

<?php

header('Content-Type: application/json');
$request = file_get_contents('php://input');

$request1=str_replace('[', '', $request);

$request2=str_replace(']', '', $request1);

$req_dump = print_r( $request2, true );

$fp = file_put_contents( 'req4.json', $req_dump );


include('ai.php');
?>

这给了我以下 JSON

REQ4.json

  "Id": 2553369,
  "ProductId": 8919892,
  "MinStock": 300,
    "ProductStockBatches": 
    "Id": 3656516,
    "StockId": 2553369,
    "CreatedDate": "2021-08-08T03:41:24.153",
    "CurrentStock": 225,
    "CurrentVolume": 0,
    "CostPrice": 0.95000,
      

所以这一切都很好,花花公子,问题出在 ai.php 中:

<?php
$servername = "localhost";
$username = "terblah";
$password = "blah";
$dbname = "blah";
try

    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->prepare("INSERT INTO blah (name, prod_id, cost, price, brand, vendor_sku, upc, code, on_hand, par,  upd_date) VALUES (:name, :prod_id, :cost, :price, :brand, :vendor_sku, :upc, :code, :currentstock, :parstock,  :upd_date) ON DUPLICATE KEY UPDATE prod_id = :prod_id");
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':prod_id', $prod_id);
    $stmt->bindParam(':cost', $cost);
    $stmt->bindParam(':price', $price);
    $stmt->bindParam(':brand', $brand);
    $stmt->bindParam(':vendor_sku', $ven_sku);
    $stmt->bindParam(':upc', $upc);
    $stmt->bindParam(':code', $code);
    $stmt->bindParam(':currentstock', $on_hand);
    $stmt->bindParam(':parstock', $par);
    $stmt->bindParam(':upd_date', $upd);
    $js = file_get_contents('req.json');
    $js0 = file_get_contents('req4.json');
    $dt = json_decode($js, true);
    $dt0 = json_decode($js0, true);
    $name = $dt['Name'];
    $prod_id = $dt0['ProductId'];
    $cost = $dt['CostPrice'];
    $price = $dt['SalePrice'];
    $brand = $dt['Supplier']['Name'];
    $ven_sku = $dt['OrderCode'];
    $code = $dt['ArticleCode'];
    $upc = $dt['Barcode'];
    $on_hand = $dt0['ProductStockBatches']['CurrentStock'];
    $par = $dt0['MinStock'];
    $upd = $dt0['ProductStockBatches']['CreatedDate'];
       
    $stmt->execute();


catch(PDOException $e)

    echo "Error: " . $e->getMessage();


$conn = null;
?>

问题是prod_id = :prod_id。 我无法将其定义为$prod_id,我这样得到以下信息:

Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

保持原样告诉我:

Error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'prod_id' cannot be null

我理解是因为我要求它搜索尚未定义的变量。当我移动定义时,我得到绑定错误,因为尚未调用要准备的语句,但我首先需要定义的键......所以我想知道我是否只是在某个地方错过了一个技巧。

我还没有尝试过,但是我想到了在ai.php中调用req4.json 2x,首先只是为了定义在重复键情况下要搜索的变量。但是如何在 SQL 语句的中间调用“$”变量呢? 我知道如何调用已定义的变量,但如何从 JSON 中提取该定义,然后将其用作 SQL 语句中的变量?

我可以

$ts = file_get_contents('req4.json');
$js1 = json_decode($ts, true);
$var = $js1['ProductId'];

然后在我的 ON DUPLICATE KEY UPDATE 中

ON DUPLICATE KEY UPDATE (prod_id = ?)

最后

$stmt->execute($var);

我试过了,我得到了

Error: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters

这让我留在这里。 我什至正确地问了这个问题吗? 有大脑目前无法工作的人可以帮帮我吗?

【问题讨论】:

虽然我知道我需要将绑定“s”定义为“?”但是我在哪里以及如何做到这一点?我迷路了。 req4.json 不是有效的 JSON。 0.95000 之间不允许使用逗号。 使用UPDATE prod_id = VALUES(prod_id) 如果你做var_dump($prod_id);,你会看到什么?看起来这个变量是空的。 哪一列是唯一列? 【参考方案1】:

您需要分配给ON DUPLICATE KEY UPDATE 中的所有其他 列。 prod_id 列是检查重复的列。

您可以使用VALUES(colname) 来获取要插入的值。

$stmt = $conn->prepare("
    INSERT INTO blah (name, prod_id, cost, price, brand, vendor_sku, upc, code, on_hand, par,  upd_date) 
        VALUES (:name, :prod_id, :cost, :price, :brand, :vendor_sku, :upc, :code, :currentstock, :parstock,  :upd_date) 
    ON DUPLICATE KEY UPDATE 
        name = VALUES(name), cost = VALUES(cost), price = VALUES(price), brand = VALUES(brand), vendor = VALUES(vendor)_sku = VALUES(sku), upc = VALUES(upc), code = VALUES(code), on = VALUES(on)_hand = VALUES(hand), par = VALUES(par),  upd = VALUES(upd)_date = VALUES(date)");

【讨论】:

以上是关于PHP/MariaDB 使用嵌套 JSON 数组进行重复键更新的主要内容,如果未能解决你的问题,请参考以下文章

如何使用材料角度将嵌套的json数组显示到html表中

使用python打印嵌套在数组中的json对象

使用 JQuery 解析 JSON 嵌套数组

在带有数组的嵌套 Json 上使用 Pandas json_normalize

Mongodb多层嵌套数组如何精确查询(内容处为格式化的json截图,评论里面是json的内容)?

使用 Dart 语言解析嵌套 JSON 数组并将其放入模型类中