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

通过Laravel中间件传递Session数据到视图时变量未定义问题求解

问题核心原因

  1. 中间件执行逻辑顺序错误
    你当前在handle方法中先执行了$response = $next($request);,这行代码会直接完成后续的路由解析、控制器逻辑执行、视图渲染全流程,你在视图渲染完成后才执行View::share,自然不会生效,渲染视图时变量还未被共享。
  2. 中间件注册位置错误
    你将中间件注册到了全局$middleware数组中,Laravel的Session初始化是在web中间件组的Illuminate\Session\Middleware\StartSession中完成的,全局中间件执行时Session还未启动,无法正确读取到Session中的购物车数据。

修正方案

第一步:调整中间件执行顺序

将购物车逻辑放在$next($request)之前执行,修正后的中间件代码如下:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use App\Models\Item;

class GetCart
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // 先执行购物车逻辑,共享变量
        $items = Item::all();
        $cartItems = [];
        for($i=0; $i < count($items); $i++){
            if(null !== Session::get('cartItem'.$i)){
                $item = Session::get('cartItem'.$i);
                array_push($cartItems, $item);
            }
        };  
        $totalNum = 0;
        for($i=0; $i < count($cartItems); $i++){
            if(isset($cartItems[$i])){
                $totalNum += $cartItems[$i]['quantity'];
            }
        }          
        View::share('cartItems', $cartItems);
        View::share('totalNum', $totalNum);
        
        // 最后执行后续请求处理、视图渲染流程
        return $next($request);
    }
}

第二步:调整中间件注册位置

删掉全局$middleware数组中的中间件注册,改到$middlewareGroups的web组中,且必须放在StartSession中间件之后:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \App\Http\Middleware\GetCart::class, // 放在StartSession之后注册
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        // ...
    ],
];

可选优化

你当前遍历全量商品匹配Session的逻辑性能较低,可以直接将购物车数据存在Session的同一个数组字段cart中,不需要每个商品单独存为cartItem+x的格式,后续读取直接拿Session::get('cart', [])即可,无需遍历全量商品。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:15:07