Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

08. SessionServiceProvider 详解 #8

Open
xiaohuilam opened this issue Sep 27, 2018 · 0 comments
Open

08. SessionServiceProvider 详解 #8

xiaohuilam opened this issue Sep 27, 2018 · 0 comments
Labels
book The digital book for laravel learning service provider The book which talk about service providers

Comments

@xiaohuilam
Copy link
Owner

xiaohuilam commented Sep 27, 2018

前言还没想好。

服务提供者部分

SessionServiceProvider 没有 boot 方法,其 register 方法为

public function register()
{
$this->registerSessionManager();
$this->registerSessionDriver();
$this->app->singleton(StartSession::class);
}

作用

下面,我们以 SESSION_DRIVER=file 继续分析
SESSION_DRIVERfile 时,会调用到 createFileDriver

protected function createFileDriver()
{
return $this->createNativeDriver();
}

createFileDriver 调用了 createNativeDriver
protected function createNativeDriver()
{
$lifetime = $this->app['config']['session.lifetime'];
return $this->buildSession(new FileSessionHandler(
$this->app['files'], $this->app['config']['session.files'], $lifetime
));
}

这里 $this->app['config']['session.files'] 得到的是

'files' => storage_path('framework/sessions'),

然后通过此处实例化 Illuminate\Session\FileSessionHandler

return $this->buildSession(new FileSessionHandler(

然后调用 buildSession 获得 \Illuminate\Session\Store 对象

protected function buildSession($handler)
{
if ($this->app['config']['session.encrypt']) {
return $this->buildEncryptedSession($handler);
}
return new Store($this->app['config']['session.cookie'], $handler);
}

session 功能 / 操作部分

读取 session

当触发 Session::start 时,

public function start()
{
$this->loadSession();
if (! $this->has('_token')) {
$this->regenerateToken();
}
return $this->started = true;
}

调用的 loadSession

protected function loadSession()
{
$this->attributes = array_merge($this->attributes, $this->readFromHandler());
}

调用的 readFromHandler

protected function readFromHandler()
{
if ($data = $this->handler->read($this->getId())) {
$data = @unserialize($this->prepareForUnserialize($data));
if ($data !== false && ! is_null($data) && is_array($data)) {
return $data;
}
}
return [];
}

这里的 read 方法,就是 FileSessionHandler::read

public function read($sessionId)
{
if ($this->files->isFile($path = $this->path.'/'.$sessionId)) {
if ($this->files->lastModified($path) >= Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {
return $this->files->sharedGet($path);
}
}
return '';
}

执行到这里时, session 中的数据就被存放到了 Illuminate\Session\Store::$attributes 了。

而执行 Session::get 时,

public function get($key, $default = null)
{
return Arr::get($this->attributes, $key, $default);
}

正好就能从 Store::$attributes 中取出 session 的数据了。

写入 session

当我们使用 Illuminate\Support\Facades\Session 时,操作是调用到的 session,也就是 Illuminate\Session\SessionManager。但是在 Illuminate\Support\Manager__call 魔术方法,实现了将 session.driver 载入到 session 中被执行的能力。

public function __call($method, $parameters)
{
return $this->driver()->$method(...$parameters);
}

有兴趣的同学请阅读 15. Laravel 神奇的 Manager 类

假如我们执行 Session::put('key', 'value')
会穿透到

public function put($key, $value = null)
{
if (! is_array($key)) {
$key = [$key => $value];
}
foreach ($key as $arrayKey => $arrayValue) {
Arr::set($this->attributes, $arrayKey, $arrayValue);
}
}

当我们手动 Session::save 时,或者程序终止运行触发 register_shutdown_function 时,会触发

public function save()
{
$this->ageFlashData();
$this->handler->write($this->getId(), $this->prepareForStorage(
serialize($this->attributes)
));
$this->started = false;
}

也就是 FileSessionHandler::write

public function write($sessionId, $data)
{
$this->files->put($this->path.'/'.$sessionId, $data, true);
return true;
}

至此,写入 session 的流程走完。

@xiaohuilam xiaohuilam changed the title 08. SessionServiceProvider 详解 [TODO] 08. SessionServiceProvider 详解 [0%] Sep 27, 2018
@xiaohuilam xiaohuilam changed the title 08. SessionServiceProvider 详解 [0%] 08. SessionServiceProvider 详解 [50%] Oct 4, 2018
@xiaohuilam xiaohuilam changed the title 08. SessionServiceProvider 详解 [50%] 08. SessionServiceProvider 详解 Oct 4, 2018
@xiaohuilam xiaohuilam added book The digital book for laravel learning service provider The book which talk about service providers labels Oct 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
book The digital book for laravel learning service provider The book which talk about service providers
Projects
None yet
Development

No branches or pull requests

1 participant