Laravel:是否可以将Session作为依赖项注入?

问题描述 投票:0回答:1

简短版

我想要实现的是使用session作为类的依赖,理想情况下使用Laravel的服务提供者。那可能吗?

长版

最近我发现服务提供商无法访问session,因为......

在Laravel中,会话由StartSession中间件处理,该中间件在所有服务提供程序引导阶段之后执行

(Qazxswpoi)

这对我来说非常不方便。我一直在创建一个购物车使用reference的电子商务网站,session应该保留客户已经收集的商品。

以下是购物车的session看起来如何......

constructor

而且,这是class Cart { private $items; public function __construct($items) { $this->items = $items; } //other functions... }

AppServiceProvider

如前所述,服务提供商无法访问class AppServiceProvider extends ServiceProvider { //boot public function register() { $this->app->bind(Cart::class, function () { return new Cart(session('cart')); }); }

所以,我把session('cart')直接放到了session('cart')的构造函数中。

Cart

通过这种方式,class Cart { private $items; public function __construct() { $this->items = session('cart'); } } 总是依赖于Cart ......但是,通过这种方法,session的依赖性(即Cart)无法用session解决,Service provider无法访问会话(如前所述)。使用这种方法,有必要使用new关键字来实例化Cart

class SomeController extends Controller
{
    private $cart;

    public function __construct(Cart $cart)
    {
        $this->cart = $cart;
    }

    public index()
    {
        $this->cart;
        //This will get null in its $items property,
        //because Service Providers can't access session

        $cart = new Cart();
        //This can get items from session()
    }
}

使用new Cart()并不是很理想。我想将Cart作为依赖注入控制器。

有没有其他方法可以使用session作为类的依赖(除了直接将它放到构造函数中)?

任何建议将被认真考虑。

php laravel session laravel-5
1个回答
1
投票

对我而言,注入会话似乎是一个非常常见的用例,而且缺少这方面的文档有点奇怪。

我已经使用Laravel 5.8会话进行了一些实验,可能会为您提供解决方案。您似乎可以键入Illuminate\Session\Store类并使用它来检索您的数据。这将产生类似下面的类:

namespace App\Test;

use Illuminate\Session\Store;

class Cart
{
    /**
     * @var \Illuminate\Session\Store
     */
    private $session;

    public function __construct(Store $session)
    {
        $this->session = $session;
    }

    public function getItems(): array
    {
        return $this->session->get('cart') ?? [];
    }

    public function addItem(string $item): void
    {
        $this->session->push('cart', $item);
    }
}

Laravel依赖项容器自动解析此类。但是,如果您想自己做这件事,您的服务提供商将会是这样的:

    public function register()
    {
        $this->app->bind(Cart::class, function (Container $container) {
            return new Cart($container->get(Store::class));
        });
    }

我认为这一切的问题在于,无法直接在服务提供商中访问会话值,但您可以访问允许您访问所述值的服务。

您认为此解决方案适合您的使用案例吗?

© www.soinside.com 2019 - 2024. All rights reserved.