PHP中如何一次性向cookie存储购物车多个商品值
问题排查结论
你的cookie存储异常完全是数组赋值逻辑错误导致的,数据库插入正常是因为SQL执行逻辑和数组赋值逻辑互不影响,具体错误点:
- 你在foreach循环中反复给
$cookie_value['product_id']/$user_basket['product_id']这个单个键赋值,后一次赋值会直接覆盖前一次的内容,循环结束后这个键只会保留最后一个遍历到的商品ID,不可能存多个值。 - 已有cookie的分支中,你在遍历修改数组之前就提前做了
serialize()序列化,后续修改数组内容不会同步到已经生成的序列化字符串里,等于修改无效。 - 数据结构设计错误:要存储多个商品ID,
product_id对应的应该是数组类型,而不是单个字符串/数字值。
修正代码
直接替换inc_panier.php的全部内容即可:
<?php if (isset($_POST['submit']) && !empty($_POST['product_id'])) { $articles = $_POST['product_id']; // 注意:直接拼接SQL存在SQL注入风险,作业阶段可暂时使用,后续建议改成预处理语句 $result = $mysqli->query('SELECT user_id, user_login FROM users WHERE user_login = "' . $_SESSION['user_login'] . '"'); $row = $result->fetch_array(); $user_id = $row['user_id']; // 初始化购物车基础结构 if (isset($_COOKIE['basket'])) { $basket = unserialize($_COOKIE['basket']); // 兼容旧的错误存储格式:如果product_id不是数组,先重置为数组格式 if (!isset($basket['product_id']) || !is_array($basket['product_id'])) { $basket['product_id'] = []; } } else { $basket = [ 'user_id' => $user_id, 'product_id' => [] ]; } foreach ($articles as $product_id) { $product_id = intval($product_id); // 转整数过滤非法参数 // 执行数据库插入 $mysqli->query('INSERT INTO basket (user_id, product_id) VALUES (' . $user_id . ', ' . $product_id . ')'); // 追加商品ID到购物车数组,判断去重避免重复添加同一件商品 if (!in_array($product_id, $basket['product_id'])) { $basket['product_id'][] = $product_id; } } // 所有数据修改完成后再序列化,写入cookie $basket_data = serialize($basket); setcookie('basket', $basket_data, time() + 1296000); } ?>
额外说明
- 修正后执行
print_r(unserialize($_COOKIE['basket'])),就能看到product_id是包含所有选中商品ID的数组,不会再出现值丢失的问题。 - 如果后续掌握JSON相关函数,建议把
serialize()/unserialize()替换成json_encode()/json_decode()存储cookie,能避免PHP反序列化带来的安全风险。 - 当前代码的SQL语句是直接拼接session、post传入的参数,存在SQL注入漏洞,掌握预处理语句后建议优先替换为参数绑定的写法。
内容的提问来源于stack exchange,提问作者Lucas Vincent
相关产品推荐
相关产品推荐

