Symfony 5.3.9用RequestStack操作Session报无法作为数组使用错误如何解决
问题根因
你遇到的报错和后续无预期结果的问题都来自两个核心错误:
- 初始版本
getCart方法直接返回了Session对象而非购物车数组,所以执行isset($cart[$id])时会触发「不能将Session对象作为数组使用」的报错 - 修改后的代码里
updateCart方法仍然写错了,没有调用Session的set方法保存购物车数据,导致修改后的购物车没有写入Session,自然获取不到更新后的值
修复方案
只需要修正CartServices.php里的updateCart方法、补全getFullCart返回值,再修正CartController里的错误调用即可,完整可运行的修正后代码如下:
修正后的CartServices.php
<?php namespace App\Services; use App\Repository\ProductRepository; use Symfony\Component\HttpFoundation\RequestStack; class CartServices { private $requestStack; private $repoProduct; public function __construct(RequestStack $requestStack, ProductRepository $repoProduct) { $this->requestStack = $requestStack; $this->repoProduct = $repoProduct; } public function addToCart($id){ $cart = $this->getCart(); if(isset($cart[$id])){ // 商品已在购物车中,数量加1 $cart[$id]++; }else{ // 商品未加入购物车,新增商品条目 $cart[$id] = 1; } $this->updateCart($cart); } public function deleteFromCart($id){ $cart = $this->getCart(); // 若商品已在购物车中 if(isset($cart[$id])){ // 若购物车中该商品数量大于1则数量减1 if($cart[$id] >1){ $cart[$id] --; }else{ // 否则删除该商品条目 unset($cart[$id]); } // 更新session数据 $this->updateCart($cart); } } public function deleteAllToCart($id){ $cart = $this->getCart(); // 若购物车中存在该商品 if(isset($cart[$id])){ // 直接删除该商品条目 unset($cart[$id]); } // 更新session数据 $this->updateCart($cart); } public function deleteCart(){ // 删除所有商品,清空购物车 $this->updateCart([]); } // 核心修改:调用session的set方法写入购物车数据 public function updateCart($cart){ $session = $this->requestStack->getSession(); $session->set('cart', $cart); } public function getCart(){ $session = $this->requestStack->getSession(); return $session->get('cart', []); } // 补充返回值,否则调用该方法会得到null public function getFullCart(){ $cart = $this->getCart(); $fullCart = []; foreach ($cart as $id => $quantity){ $product = $this->repoProduct->find($id); if($product){ // 商品查询成功 $fullCart[]=[ 'quantity' => $quantity, 'product' => $product ]; }else{ // 商品id不合法 $this->deleteFromCart($id); // 无需手动更新session,deleteFromCart方法已包含更新逻辑 } } return $fullCart; } }
修正后的CartController.php
<?php namespace App\Controller; use App\Services\CartServices; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class CartController extends AbstractController { /** * @Route("/cart/add/{id}", name="cart_add") */ public function addToCart($id,CartServices $cartServices):Response { $cartServices->addToCart($id); // 去掉getCart方法多余的传参 dd($cartServices->getCart()); return $this->render('cart/index.html.twig', [ 'controller_name' => 'CartController', ]); } }
补充说明
你当前用RequestStack获取Session的写法完全符合Symfony 5.3+的规范,不需要再注入已经废弃的SessionInterface,修改完以上代码即可正常读写购物车Session。
内容的提问来源于stack exchange,提问作者TBA
相关产品推荐
相关产品推荐

