Laravel在中间件中设置cookie,因此它可以在同一请求中使用

时间:2017-01-24 14:39:04

标签: php laravel

我有一个Laravel中间件,如果它已经不存在,它会设置一个cookie:

public function handle($request, Closure $next)
    {
        if (!$request->cookie('cart_id')) {
            return $next($request)->withCookie(cookie()->forever('cart_id', $this->generateUniqueCartId()));
        }

        return $next($request);
    }

简单!问题是如果我尝试在同一请求上从Controller访问该cookie,它将返回null

$request->cookie('cart_id')

仅在后续请求中包含请求包含cookie。

我了解原始请求从未包含Cookie,因此返回null是有意义的,但我想知道是否有干净方式访问它或者我是否必须将其闪存到会话中以便稍后在该请求中访问它?

1 个答案:

答案 0 :(得分:3)

我通过创建一个专门处理该购物车Cookie生成并使其成为注入服务容器的单例类的类来解决我的问题。

一旦它生成一个唯一的购物车ID,它就会存储它,以便稍后我可以使用app(CartCookie::class)->id()在同一个请求中访问它。如果有人能想出一个更干净的方式,那么请务必告诉我。

以下是代码:

CartCookie.php

namespace App\Services;

use App\Cart;
use Illuminate\Http\Request;

class CartCookie
{
    private $id;
    private $request;

    function __construct(Request $request)
    {
        $this->request = $request;

        if ($request->cookie('cart_id')) {
            $this->id = $request->cookie('cart_id');
        } else {
            $this->id = $this->generateUniqueCartId();
        }
    }

    public function id()
    {
        return $this->id;
    }

    private function generateUniqueCartId()
    {
        do {
            $id = md5(time() . 'cart' . rand(100000000000000, 9999999999999999));
        } while (Cart::find($id));

        return $id;
    }
}

CartCookieServiceProvider.php

namespace App\Providers;

use App\Services\CartCookie;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

class CartCookieServiceProvider extends ServiceProvider
{
    public function boot(Request $request)
    {
        $this->app->singleton(CartCookie::class, function ($app) use ($request) {
            return new CartCookie($request);
        });
    }
}

CartCookieMiddleware.php

namespace App\Http\Middleware;

use App\Cart;
use Closure;

class CartCookie
{
    public function handle($request, Closure $next)
    {
        if (!$request->cookie('cart_id')) {
            $id = app(\App\Services\CartCookie::class)->id();

            return $next($request)->withCookie(cookie()->forever('cart_id', $id));
        }

        return $next($request);
    }
}