laravel session 源码分析
粗略阅读过session 源码 大概有以下几个东西
1.SessonManager 这个laravel 喜欢用的代理类
2.*SessionHandler 各种处理类
3 .Store类 依赖 各种处理类 也相当于 各种处理类的 代理类 实际操作 还是各种handler 处理类
示列
Session::get();
1. 首先是门面类 肯定是找到Session门面对应的类 session 然后相当于 make('session')其实就是new 的SessionManager类
2.然后就是 调用SessionManager的 get方法 但是这个方法不存在 所以就去寻找 __call方法;一看还真有。下面看下这个方法
/** * Dynamically call the default driver instance. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->driver()->$method(...$parameters); }
那么driver是什么呢
/** * Get a driver instance. * * @param string|null $driver * @return mixed * * @throws \InvalidArgumentException */ public function driver($driver = null) { $driver = $driver ?: $this->getDefaultDriver(); if (is_null($driver)) { throw new InvalidArgumentException(sprintf( 'Unable to resolve NULL driver for [%s].', static::class )); } // If the given driver has not been created before, we will create the instances // here and cache it so we can return it next time very quickly. If there is // already a driver created by this name, we'll just return that instance. if (! isset($this->drivers[$driver])) { $this->drivers[$driver] = $this->createDriver($driver); } return $this->drivers[$driver]; }
下面看看 $this->createDriver($driver)
/** * Create an instance of the "cookie" session driver. * * @return \Illuminate\Session\Store */ protected function createCookieDriver() { return $this->buildSession(new CookieSessionHandler( $this->container->make('cookie'), $this->config->get('session.lifetime') )); }
再看看看 buildSession
/** * Build the session instance. * * @param \SessionHandlerInterface $handler * @return \Illuminate\Session\Store */ protected function buildSession($handler) { return $this->config->get('session.encrypt') ? $this->buildEncryptedSession($handler) : new Store($this->config->get('session.cookie'), $handler); }
最后返回的就是一个Sotre的类
那么我们猜 get方法 肯定是Store的方法了. 我们来看看呢
/** * Get an item from the session. * * @param string $key * @param mixed $default * @return mixed */ public function get($key, $default = null) { return Arr::get($this->attributes, $key, $default); }
还真的有。。。
最后的疑问 就是 $this->attributes 这个属性是哪里来的呢? 可能我看没读完,,,
隔了一会-------------------------找到答案了
通过源码阅读 可以看到 session的启动 是在中间件里面启动的
/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if (! $this->sessionConfigured()) { return $next($request); } $session = $this->getSession($request); if ($this->manager->shouldBlock() || ($request->route() && $request->route()->locksFor())) { return $this->handleRequestWhileBlocking($request, $session, $next); } else { return $this->handleStatefulRequest($request, $session, $next); } }
看最后一个方法
/** * Handle the given request within session state. * * @param \Illuminate\Http\Request $request * @param \Illuminate\Contracts\Session\Session $session * @param \Closure $next * @return mixed */ protected function handleStatefulRequest(Request $request, $session, Closure $next) { // If a session driver has been configured, we will need to start the session here // so that the data is ready for an application. Note that the Laravel sessions // do not make use of PHP "native" sessions in any way since they are crappy. $request->setLaravelSession( $this->startSession($request, $session) ); $this->collectGarbage($session); $response = $next($request); $this->storeCurrentUrl($request, $session); $this->addCookieToResponse($response, $session); // Again, if the session has been configured we will need to close out the session // so that the attributes may be persisted to some storage medium. We will also // add the session identifier cookie to the application response headers now. $this->saveSession($request); return $response; }
然后 通过 $this->startSession($request, $session)
/** * Start the session for the given request. * * @param \Illuminate\Http\Request $request * @param \Illuminate\Contracts\Session\Session $session * @return \Illuminate\Contracts\Session\Session */ protected function startSession(Request $request, $session) { return tap($session, function ($session) use ($request) { $session->setRequestOnHandler($request); $session->start(); }); }
看到没 最后一句 start函数
/** * Start the session, reading the data from a handler. * * @return bool */ public function start() { $this->loadSession(); if (! $this->has('_token')) { $this->regenerateToken(); } return $this->started = true; }
接着追
/** * Load the session data from the handler. * * @return void */ protected function loadSession() { $this->attributes = array_merge($this->attributes, $this->readFromHandler()); }
看到没 终于知道attribute属性 是哪里来的了。