1. Используя алиас Session:
$session = Session::get('key');
2. Метод session() объекта запроса ($request):
public function showProfile(Request $request, $id) { $value = $request->session()->get('key'); }при этом объект текущего запроса нужно передать в виде зависимости - в качестве аргумента действия контроллера.
3. С помощью функции помощника session():
$session3 = session('key');Данная функция обычно используется для простого извлечения и помещения данных в сессию, но
при вызове функции session() без аргументов, она возвратит весь объект сессии, который далее можно использовать для вызова нужных методов:
session()->put('ksl', 2104);
В любом случае, вызов требуемого метода, будет обращен к объекту класса SessionManager который на самом деле не содержит пользовательских методов для работы с сессиями, а передает запрос дальше.
В этой статье я хочу рассказать через какие классы и куда именно проходит запрос при вызове различных методов, допустим того же get().
Например рассмотрим обращение к алиасу (псевдониму) сессии. Он прописан в файле config\app.php:
'Session' => Illuminate\Support\Facades\Session::class,при обращении к алиасу Session, возвращается значение указанное в методе getFacadeAccessor() класса фасада сессии из файла vendor\laravel\framework\src\Illuminate\Support\Facades\Session.php
Данное значение связывает алиас (может быть любым) с идентификатором, под которым в глобальной переменной приложения хранится объект SessionManager. Данный объект создается при начальной загрузке приложения с помощью провайдера данных SessionServiceProvider прописанного в файле config\app.php в массиве providers:
Illuminate\Session\SessionServiceProvider::class,
Приложение выполняет метод register() для каждого из указанных в данном массиве провайдеров. В данном случае:
public function register() { $this->registerSessionManager(); $this->registerSessionDriver(); $this->app->singleton(StartSession::class); }в первой строке вызов метода registerSessionManager() создает объект класса SessionManager и сохраняет его в глобальное свойство приложения app:
protected function registerSessionManager() { $this->app->singleton('session', function ($app) { return new SessionManager($app); }); }
Как раз тут видно, что фасад сессий связан с идентификатором под которым хранится данный объект и который указывается первым аргументом для метода singleton(). Данный метод реализует шаблон проектирования «синглтон» и обеспечивает, при каждом запросе объекта (в данном случае сессий), передачу одного и того же объекта без создания нового.
Вызов второй строки - метода registerSessionDriver():
protected function registerSessionDriver() { $this->app->singleton('session.store', function ($app) { return $app->make('session')->driver(); }); }в свойстве глобального объекта app регистрируется драйвер, указанный в настройках для хранения сессии (выбранный способ хранения данных - в файле, в базе данных и др.)
В третьей строке, вызов
$this->app->singleton(StartSession::class);регистрирует в свойстве глобального объекта приложения класс-посредник StartSession (файл vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php).
Данный посредник должен быть прописан в классе Kernel файла app\Http\Kernel.php (по-умолчанию уже прописан для группы web в Laravel 5.4) для включения механизма сессий.
Объект класса SessionManager не содержит основных методов для рабты с сессиями, таких как
Session::get()
Session::put()
и других.
Данный класс наследует от класса Manager (файл vendor\laravel\framework\src\Illuminate\Support\Manager.php). Данный абстрактный класс, в своей структуре, содержит вызов магического метода __call():
public function __call($method, $parameters) { return $this->driver()->$method(...$parameters); }который принимает вызовы любых несуществующих методов данного или дочернего классов.
В начале вызывается метод driver() который должен получить и вернуть экземпляр драйвера (под драйвером понимается класс работающий с указанным в настройках типом хранения сессий - в файле, в базе данных, памяти и тд.). Вот код данного метода:
public function driver($driver = null) { $driver = $driver ?: $this->getDefaultDriver(); if (! isset($this->drivers[$driver])) { $this->drivers[$driver] = $this->createDriver($driver); } return $this->drivers[$driver]; }
Тут в переменную $driver попадает вызов метода getDefaultDriver() дочернего класса (SessionManager):
public function getDefaultDriver() { return $this->app['config']['session.driver']; }
который возвращает установленный в настройках драйвер сессии (место хранения данных сессии – файл, база данных или др.). Данный драйвер устанавливается в файле .env:
SESSION_DRIVER=file
Потом значение переносится в общий файл настроек сессии – файл config\session.php.
В нашем случае (как и в большинстве) сохранение сессий установлено в файл, а значит метод getDefaultDriver() вернет значение «file».
Далее в свойство drivers класса Manager попадает результат работы метода createDriver() Создающий новый экземпляр драйвера:
protected function createDriver($driver) { if (isset($this->customCreators[$driver])) { return $this->callCustomCreator($driver); } else { $method = 'create'.Str::studly($driver).'Driver'; if (method_exists($this, $method)) { return $this->$method(); } } throw new InvalidArgumentException("Driver [$driver] not supported."); }который из названия «file» формирует название метода - createFileDriver(), а далее этот метод и вызывается (в дочернем классе - SessionManager):
protected function createFileDriver() { return $this->createNativeDriver(); }
В нем происходит вызов метода createNativeDriver(), который создает экземпляр драйвера:
protected function createNativeDriver() { $lifetime = $this->app['config']['session.lifetime']; return $this->buildSession(new FileSessionHandler( $this->app['files'], $this->app['config']['session.files'], $lifetime )); }
Создается объект класса FileSessionHandler получающий в качестве аргументов текущие настройки работы с сессиями в т.ч. время сессии. Далее этот объект передается в качестве аргумента методу buildSession():
protected function buildSession($handler) { if ($this->app['config']['session.encrypt']) { return $this->buildEncryptedSession($handler); } else { return new Store($this->app['config']['session.cookie'], $handler); } }который и возвращает, созданный с учетом настроек (передаются в его конструктор), объект класса Store (файл vendor\laravel\framework\src\Illuminate\Session\Store.php).
В итоге при вызове методов работы с сессиями обращение происходит как раз к объекту класса Store.
Отмечу еще, что, по-умолчанию, файлы сессий хранятся в папке storage\framework\sessions.