2 回答
TA贡献1946条经验 获得超3个赞
我在您的查询中检测到两个错误:
您插入 5 个字段,但只有 4 个值。
在值中,如果值字符串,则不添加 '' char
示例:如果所有数据类型为字符串的字段
VALUES ('$products[$i]', '$ids_product_attribute[$i]', '$references[$i]', '$stocks[$i]', 'Field 5')TA贡献1804条经验 获得超8个赞
我会这样写这个函数:
public function hookActionValidateOrder()
{
$defaults = [
'id_product' => null,
'id_product_attribute' => null,
'reference' => 0,
'stock_quantity' => 0
];
$stmt = Db::getInstance()->prepare("
INSERT INTO cart_log
SET products = :id_product,
ids_product_attribute = :id_product_attribute,
references = :reference,
stocks = :stock_quantity");
$products = Context::getContext()->cart->getProducts();
foreach ($products as $product) {
$values = array_merge($defaults, array_intersect_key($product, $defaults));
$stmt->execute($values);
}
}
此示例显示了在准备好的语句中查询参数的用法,因此您不要尝试将 PHP 变量直接插入到 SQL 查询中。查询参数使编写无错误的 SQL 代码变得更加容易,并且它们可以保护您免受意外 SQL 注入错误(也包括恶意攻击)的影响。
我建议您调用cart->getProducts()一次,并将结果保存在局部变量中。我不确定该函数的作用,但我想它正在运行另一个 SQL 查询。您不应该为每个循环多次运行相同的 SQL 查询,这会增加数据库服务器的负载。
要做的事情array_merge(array_intersect_key())是确保 values 数组具有所有需要的键,并且除了需要的键之外没有其他键。然后它可以按原样传递给PDOStatement::execute().
我正在使用MySQL 支持的INSERT 替代形式,使用SET column = value ...语法。我发现这可以更轻松地确保我已将一列与每个值匹配,反之亦然。
正如上面评论中提到的,您必须在数据库连接器中启用异常。我假设您的getInstance()函数返回一个 PDO 连接,因此您可以将参数数组传递给execute(). 您需要按照此处所述启用 PDO 异常:https ://www.php.net/manual/en/pdo.error-handling.php
如果您不启用异常,则应检查 和 的返回值prepare()是否为 ,execute()如果是=== false,则记录errorInfo()(阅读我链接到的关于错误处理的 PHP 文档)。
- 2 回答
- 0 关注
- 284 浏览
添加回答
举报
