内容简介:执行php脚本,session_start()会从php.ini中读取配置项,将生成的唯一值sessionID保存文件放到配置项中的保存路径和地点。并通过HTTP协议返回响应消息头setCookie客户端接受到Set-Cookie,将cookie值写入cookie文件在接下来的访问中,客户端会携带cookie访问浏览器,浏览器接受到cookie值,生成http请求头将包含的COOKIE发送给Php,php识别cookie值,从保存路径中找对应的文件。
1、 php 如何实现session
执行php脚本,session_start()会从php.ini中读取配置项,将生成的唯一值sessionID保存文件放到配置项中的保存路径和地点。并通过HTTP协议返回响应消息头setCookie
客户端接受到Set-Cookie,将cookie值写入cookie文件
在接下来的访问中,客户端会携带cookie访问浏览器,浏览器接受到cookie值,生成http请求头将包含的COOKIE发送给Php,php识别cookie值,从保存路径中找对应的文件。
找到文件之后,检验是否在有效期内,在有效期内就读取文件,不再有效期内就清空文件
2、自己实现session需要考虑的几个问题
1)、生成唯一值的算法
2)、将session存到文件里还是存到 redis 还是memcache,应该存什么数据
3)、接受cookie值,从保存位置找到对应的文件或数据
4)、session垃圾回收机制,删除session文件和数据
5)、分布式的话,session同步问题
3、分析一下 laravel 如何实现session.
vendor/laravel/framework/src/Illuminate/Contracts定义都是接口类(契约)。
<?php namespace Illuminate\Contracts\Session; interface Session { public function getName();//获得session名字 public function getId();//获得当前sessionID public function setId($id);//修改sessionID public function start();//启动session,从配置文件中读取数据 public function save();//将session数据保存 public function all();//获得所有的session public function exists($key);//检查session名称是否存在 public function has($key);//检查session名称是否存在和不为空 public function get($key, $default = null);//通过session名称获取session值 public function put($key, $value = null);//将session名称和session值存入session文件或数据库 public function token(); //获得csrf token的值 public function remove($key);//根据session名称删除session信息 public function forget($keys);//根据session名称删除session信息 public function flush();//清空所有的session内容 public function migrate($destroy = false); //为session会话创建一个新的session会话 public function isStarted();//确定会话是否启动 public function previousUrl();//从会话中获取session的url public function setPreviousUrl($url);//设置previous的url存入session public function getHandler();//获得session处理实例 public function handlerNeedsRequest();//确定会话程序是否需要请求 public function setRequestOnHandler($request);//在处理请求实例上设置请求 }
实现接口类的具体实现类只有一个vendor/laravel/framework/src/Illuminate/Session/Store.php
<?php namespace Illuminate\Session; use Closure; use stdClass; use Illuminate\Support\Arr; use Illuminate\Support\Str; use SessionHandlerInterface; use Illuminate\Contracts\Session\Session; class Store implements Session { protected $id; protected $name; protected $attributes = []; protected $handler; protected $started = false; public function __construct($name, SessionHandlerInterface $handler, $id = null) { $this->setId($id); $this->name = $name; $this->handler = $handler; } public function start() { $this->loadSession(); if (! $this->has('_token')) { $this->regenerateToken(); } return $this->started = true; } protected function loadSession() { $this->attributes = array_merge($this->attributes, $this->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 []; } protected function prepareForUnserialize($data) { return $data; } public function save() { $this->ageFlashData(); $this->handler->write($this->getId(), $this->prepareForStorage( serialize($this->attributes) )); $this->started = false; } protected function prepareForStorage($data) { return $data; } public function ageFlashData() { $this->forget($this->get('_flash.old', [])); $this->put('_flash.old', $this->get('_flash.new', [])); $this->put('_flash.new', []); } public function all() { return $this->attributes; } public function exists($key) { $placeholder = new stdClass; return ! collect(is_array($key) ? $key : func_get_args())->contains(function ($key) use ($placeholder) { return $this->get($key, $placeholder) === $placeholder; }); } public function has($key) { return ! collect(is_array($key) ? $key : func_get_args())->contains(function ($key) { return is_null($this->get($key)); }); } public function get($key, $default = null) { return Arr::get($this->attributes, $key, $default); } public function pull($key, $default = null) { return Arr::pull($this->attributes, $key, $default); } public function hasOldInput($key = null) { $old = $this->getOldInput($key); return is_null($key) ? count($old) > 0 : ! is_null($old); } public function getOldInput($key = null, $default = null) { return Arr::get($this->get('_old_input', []), $key, $default); } public function replace(array $attributes) { $this->put($attributes); } public function put($key, $value = null) { if (! is_array($key)) { $key = [$key => $value]; } foreach ($key as $arrayKey => $arrayValue) { Arr::set($this->attributes, $arrayKey, $arrayValue); } } public function remember($key, Closure $callback) { if (! is_null($value = $this->get($key))) { return $value; } return tap($callback(), function ($value) use ($key) { $this->put($key, $value); }); } public function push($key, $value) { $array = $this->get($key, []); $array[] = $value; $this->put($key, $array); } public function increment($key, $amount = 1) { $this->put($key, $value = $this->get($key, 0) + $amount); return $value; } public function decrement($key, $amount = 1) { return $this->increment($key, $amount * -1); } public function flash(string $key, $value = true) { $this->put($key, $value); $this->push('_flash.new', $key); $this->removeFromOldFlashData([$key]); } public function now($key, $value) { $this->put($key, $value); $this->push('_flash.old', $key); } public function reflash() { $this->mergeNewFlashes($this->get('_flash.old', [])); $this->put('_flash.old', []); } public function keep($keys = null) { $this->mergeNewFlashes($keys = is_array($keys) ? $keys : func_get_args()); $this->removeFromOldFlashData($keys); } protected function mergeNewFlashes(array $keys) { $values = array_unique(array_merge($this->get('_flash.new', []), $keys)); $this->put('_flash.new', $values); } protected function removeFromOldFlashData(array $keys) { $this->put('_flash.old', array_diff($this->get('_flash.old', []), $keys)); } public function flashInput(array $value) { $this->flash('_old_input', $value); } public function remove($key) { return Arr::pull($this->attributes, $key); } public function forget($keys) { Arr::forget($this->attributes, $keys); } public function flush() { $this->attributes = []; } public function invalidate() { $this->flush(); return $this->migrate(true); } public function regenerate($destroy = false) { return tap($this->migrate($destroy), function () { $this->regenerateToken(); }); } public function migrate($destroy = false) { if ($destroy) { $this->handler->destroy($this->getId()); } $this->setExists(false); $this->setId($this->generateSessionId()); return true; } public function isStarted() { return $this->started; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function getId() { return $this->id; } public function setId($id) { $this->id = $this->isValidId($id) ? $id : $this->generateSessionId(); } public function isValidId($id) { return is_string($id) && ctype_alnum($id) && strlen($id) === 40; } protected function generateSessionId() { return Str::random(40); } public function setExists($value) { if ($this->handler instanceof ExistenceAwareInterface) { $this->handler->setExists($value); } } public function token() { return $this->get('_token'); } public function regenerateToken() { $this->put('_token', Str::random(40)); } public function previousUrl() { return $this->get('_previous.url'); } public function setPreviousUrl($url) { $this->put('_previous.url', $url); } public function getHandler() { return $this->handler; } public function handlerNeedsRequest() { return $this->handler instanceof CookieSessionHandler; } public function setRequestOnHandler($request) { if ($this->handlerNeedsRequest()) { $this->handler->setRequest($request); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- AOP如何实现及实现原理
- webpack 实现 HMR 及其实现原理
- Docker实现原理之 - OverlayFS实现原理
- 为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性?
- 自己实现集合框架(十):顺序栈的实现
- php实现mysql连接池效果实现代码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。