【问题标题】:Laravel: Is it possible to inject Session as a dependency?Laravel:是否可以将 Session 作为依赖项注入?
【发布时间】:2019-09-04 04:05:12
【问题描述】:

短版

我想要实现的是使用 session 作为类的依赖项,最好是使用 Laravel 的服务提供者。这可能吗?

长期版本

最近发现session不能被服务商访问,因为...

在 Laravel 中,会话由 StartSession 中间件处理,该中间件在所有服务提供者启动阶段之后执行

(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 解决,这可以't 访问会话(如前所述)。使用这种方法,必须使用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】:

    在我看来,注入 Session 似乎是一个很常见的用例,但缺少这方面的文档有点奇怪。

    我已经对 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));
            });
        }
    

    我认为整个事情的问题是会话值不能直接在服务提供者中访问,但您可以访问使您可以访问所述值的服务。

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

    【讨论】:

    • 看起来很棒!我会尝试这种方法。谢谢你的建议!
    猜你喜欢
    • 1970-01-01
    • 2022-05-07
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多