Laravel: Возможно ли внедрить Session как зависимость? - PullRequest
0 голосов
/ 13 апреля 2019

Короткая версия

Чего я хочу добиться, так это использовать session в качестве зависимости класса, в идеале с поставщиком услуг Laravel.Возможно ли это?

Длинная версия

Недавно я обнаружил, что поставщики услуг не могут получить доступ к session, потому что ...

в Laravel сеанс обрабатывается промежуточным программным обеспечением StartSession, которое выполняется после фазы загрузки всех поставщиков услуг

( ссылка )

Это довольно неудобно для меня.Я создавал сайт электронной коммерции, на котором в корзине покупок используется 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 в качестве зависимости класса (кроме непосредственного помещения его в конструктор)?

Любой совет будет оценен.

1 Ответ

1 голос
/ 14 апреля 2019

Мне кажется, что внедрение сеанса является довольно распространенным вариантом использования, и это немного странно, документации для этого не хватает.

Я немного поэкспериментировал с сеансами 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));
        });
    }

Я думаю, что смысл всего этого заключается в том, что значения сеанса не могут быть доступны напрямую у поставщика услуг, но вы можете получить доступ к сервису, который дает вам доступ к указанным значениям.

Как вы думаете, это решение подойдет для вашего случая использования?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...