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

PrestaShop模块hookActionPaymentConfirmation数据库连接及更新问题排查

PrestaShop模块hookActionPaymentConfirmation数据库操作故障排查

先看你代码里的几个致命问题,直接导致代码跑不起来:

核心错误点

  • 未定义变量$campoid:你在SQL语句里直接用了$campoid,但代码里完全没给这个变量赋值,执行到这里直接报错终止,这是最关键的问题。
  • 数据库连接无错误检查:实例化DbMySQLi后,没有判断连接是否成功,根本不知道是连不上库还是后续逻辑错了。
  • getValue方法误用:getValue是用来获取单值结果的,你用它执行select *,只会返回第一列的第一个值,根本拿不到整行数据,$rec["reference"]必然报错。
  • SQL拼接存在注入风险+语法错误隐患:直接把变量拼进SQL,遇到带引号、特殊字符的$referencia会直接导致SQL语法错误,同时有注入风险。
  • Order实例化未做有效性校验:如果$params['id_order']无效,new Order()会返回false,后续调用getCartProducts()直接报错。
  • 配置参数未做非空检查:如果Configuration::get没取到数据库参数,$database/$user/$password会是null,直接传给DbMySQLi会导致连接失败。

修正后的代码示例

public function hookActionPaymentConfirmation($params)
{
    // 先检查必要参数是否存在
    $database = Configuration::get('MIMODULOMISMADB_ACCOUNT_NOMBREDB');
    $user = Configuration::get('MIMODULOMISMADB_ACCOUNT_USUARIO');
    $password = Configuration::get('MIMODULOMISMADB_ACCOUNT_PASSWORD');
    // 定义缺失的$campoid变量,根据你的productos表实际字段修改
    $campoid = 'referencia';

    if (empty($database) || empty($user)) {
        mail("luilli.guillan@gmail.com", "错误", "数据库配置参数缺失");
        return;
    }

    // 初始化数据库连接并检查是否成功
    $db = new DbMySQLi("localhost", $user, $password, $database, true);
    if (!$db->connect()) {
        mail("luilli.guillan@gmail.com", "连接失败", $db->getMsgError());
        return;
    }

    // 检查订单是否有效
    if (!isset($params['id_order']) || !($order = new Order($params['id_order'])) || !Validate::isLoadedObject($order)) {
        mail("luilli.guillan@gmail.com", "错误", "无效的订单ID");
        return;
    }

    $products = $order->getCartProducts();
    if (empty($products)) {
        mail("luilli.guillan@gmail.com", "提示", "订单无商品");
        return;
    }

    foreach ($products as $product) {
        $id_product = (int)$product['id_product'];
        $cantidad = (int)$product['cart_quantity'];
        $referencia = $product['reference'];
        $product_attribute_id = (int)$product['product_attribute_id'];

        $newProduct = new Product($id_product);
        if ($newProduct->hasCombinations() && $product_attribute_id > 0) {
            // 用getRow获取整行数据,而非getValue
            $sql = 'SELECT reference FROM product_attribute WHERE id_product_attribute = ' . (int)$product_attribute_id;
            $rec = $db->getRow($sql);
            if ($rec && isset($rec['reference'])) {
                $referencia = $rec['reference'];
            }
        }

        // 用pSQL处理变量避免SQL注入和语法错误
        $unidades = $db->getValue('SELECT unidades FROM productos WHERE ' . pSQL($campoid) . ' = "' . pSQL($referencia) . '"');
        $unidades = (int)$unidades;
        $unidadesRestantes = $unidades - $cantidad;

        $updateSql = 'UPDATE productos SET unidades = ' . (int)$unidadesRestantes . ' WHERE ' . pSQL($campoid) . ' = "' . pSQL($referencia) . '"';
        if (!$db->Execute($updateSql)) {
            mail("luilli.guillan@gmail.com", "更新失败", "SQL: " . $updateSql . " 错误: " . $db->getMsgError());
        } else {
            mail("luilli.guillan@gmail.com", "更新成功", "商品" . $referencia . "库存从" . $unidades . "变为" . $unidadesRestantes);
        }
    }
}

排查步骤建议

  1. 先补全$campoid变量,赋值为你productos表中对应商品编码的字段名,比如'codigo'或者'referencia'。
  2. 开启PrestaShop调试模式:在config/defines.inc.php里把_PS_MODE_DEV_设为true,能直接看到具体报错信息,比邮件调试高效得多。
  3. 单独测试数据库连接:写一段简单代码验证配置参数能不能正常连上目标数据库,先排除连接问题。
  4. 逐步调试:先注释循环里的SQL操作,只保留邮件输出订单、商品信息,确认钩子能正常触发,再逐步加回数据库操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:16:12