1、Session的由来及其实现

HTTP协议是无状态的协议,同一个客户端的这次请求和上次请求是没有对应关系的。也就是说我们无法在服务器端确认两次请求是否是同一个用户所为,这为我们在一些应用场景中实现在多次请求间记住用户状态带来麻烦,比如电子商务网站,用户浏览商品、加入购物车、下单、购买需要多个请求才能完成,如果在这些请求之间无法记住用户状态,根本无法完成正常的购买行为,为此,引入了Session的概念,其目的就是在请求中记住用户状态。

Session的实现机制有两种,一种是我们通常所见的基于Cookie,即将针对每个用户生成的唯一Session ID存放在Cookie中,然后用户每次请求都会带上这个Session ID,这样服务器端就能判断是否是同一个用户,这种机制需要浏览器支持Cookie(现在的浏览器默认都支持);另一种是将基于URL重写,即将Session ID作为参数放到URL中,这样每次请求也会带上Session ID,当浏览器不支持Cookie时可以使用这种方式。

上述两种实现机制是针对客户端的,服务器端也可以将Session存放到不同介质,常见的存储方式有文件、数据库、 Memcached 和Redis等。和之前的缓存、队列一样,Laravel也为不同的存储提供了统一的接口,下面我们就来看一下如何在Laravel中实现Session的存储、访问、删除以及更多其它用法。

2、Session配置

Laravel 中 Session 配置文件位于 config/session.php ,默认设置如下:

return [
'driver' => env('SESSION_DRIVER', 'file'),
'lifetime' => 120,
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => null,
'table' => 'sessions',
'lottery' => [2, 100],
'cookie' => 'laravel_session',
'path' => '/',
'domain' => null,
'secure' => false,
];

driver 配置项用于设置Session存储方式,默认是 file ,即存储在文件中,该文件位于 files 配置项配置的路径,即 storage/framework/sessions 。此外Laravel还支持其它存储方式:

  • database :将Session数据存放到指定数据表中,该数据表由配置项 table 设置
  • memcached :将Session数据存放到Memcached中
  • redis :将Session数据存放到Redis中
  • array :将Session数据存放到数组中,该配置仅用于测试环境

要修改 driver 配置,需要去项目根目录下 .env 文件修改其中的 SESSION_DRIVER 选项。

lifetime 配置项用于设置Session有效期,默认为120分钟。

expire_on_close 配置项用于设置是否在浏览器关闭时立即让Session失效。

encrypt 配置项用于配置Session数据是否加密。

lottery 配置项用于配置回收Session存放位置。

cookie 配置项用于配置存放Session ID的Cookie名称,默认是 laravel_session。

path 配置项用于配置存放Session ID的Cookie存放路径,默认为项目根目录。

domain 配置项用于配置存放Session ID的Cookie存放域名。

secure 配置项用于配置是否只有在HTTPS协议下发送Session ID到服务器。

使用数据库存储Session

需要将 .env 文件中的SESSION_DRIVER修改为 database ,然后将 config/session.php 中 connection 配置修改为 mysql (如果使用的数据库是MySQL的话),该配置值对应 config/database.php 中 connections 相应数据库配置项,也可以使用默认值 null 不做修改。

然后需要在项目根目录下运行如下Artisan命令:

php artisan session:table
composer dump-autoload
php artisan migrate

生成存放Session的数据表 sessions 。

使用Memcached/Redis存储Session

使用Memcached存储Session只需将 .env 文件中SESSION_DRIVER修改为 memcached 即可。

使用Redis存储Session需要将 .env 文件中SESSION_DRIVER修改为 redis ,然后将 config/session.php 中 connection 配置修改为 default (对应 config/database.php 中 redis 主机配置项),当然也可以使用默认值 null 不做修改。

这里我们使用默认配置不做改变(使用文件存储Session)。

3、Session 使用示例

其实我们之前已经接触到了Session存储,比如之前的用户登录就会用到,用户登录成功之后会将用户数据存放到Session中。这里我们使用Session存放一些简单的测试数据。

使用帮助函数session

存放Session可以使用全局帮助函数 session :

session(['site'=>'LaravelAcademy.org']);

对应Session的访问方法:

$site = session('site');

此外还支持对Session数组操作:

session(['site.xxx'=>'LaravelAcademy.org']);
$site = session('site');
dd($site);

打印结果为:

使用Request实例

以上是快捷存取Session,我们还可以在Request实例上实现对Session更高级的一些操作。

我们可以以这种方式获取所有Session数据:

$sessions = $request->session()->all();

我们可以像这样存取Session数据:

$request->session()->put('site', 'http://LaravelAcademy.org');
if($request->session()->has('site')){
$site = $request->session()->get('site');
dd($site);
}

此外还可以这样获取Session数据(如果对应Session不存在,返回默认值):

$sitename = $request->session()->get('sitename','Laravel学院');
dd($sitename);

此外还可以使用 push 方法推送多个数据到Session数组:

$request->session()->push('site.xxx', 'http://LaravelAcademy.org');
$request->session()->push('site.xxx', 'Laravel学院');
if($request->session()->has('site')){
$site = $request->session()->get('site');
dd($site);
}

对应输出为:

当然我们可以使用如下方式实现异曲同工之效:

$request->session()->put('site.xxx', ['http://LaravelAcademy.org','Laravel学院']);

我们可以使用 pull 方法获取数据然后将其删除:

$siteid = $request->session()->pull('siteid','LaravelAcademy');
echo $siteid; $siteid = $request->session()->get('siteid');
echo $siteid;

结果只能打印一个 LaravelAcademy 。

删除指定Session数据还可以使用 forget 方法:

$request->session()->put('site.name','Laravel学院');

$sitename = session('site.name');
echo $sitename; $request->session()->forget('site.name'); $sitename = session('site.name');
echo $sitename;

结果只能打印一个 Laravel学院 。

还可以通过 flush 方法一次性删除所有Session数据:

$request->session()->flush();
$sessions = $request->session()->all();
dd($sessions);

打印结果为空数组。

一次性Session数据

所谓一次性数据就是下一次请求中(仅仅是下一次)有效的Session数据,常见的应用场景就是表单验证错误信息。用法也很简单,使用 flash 方法即可。

比如我们在 TestController@session 中编写测试代码如下:

public function session(Request $request){
$request->session()->flash('message', '欢迎访问Laravel学院!');
}

然后在 TestController@sessionx 中编写测试代码如下:

public function sessionx(){
$message = session('message');
echo $message;
}

然后在 routes.php 中定义路由规则如下:

Route::get('test/session','TestController@session');
Route::get('test/sessionx','TestController@sessionx');

在浏览器中访问 http://laravel.app:8000/test/session ,然后再访问 http://laravel.app:8000/test/sessionx,打印出:

欢迎访问Laravel学院!

再次刷新 http://laravel.app:8000/test/sessionx ,则页面显示空白,说明Session数据已经被销毁,这就是一次性Session数据。

当然,如果我们想要继续保持一次性Session数据有效,可以定义 TestController@sessionx 代码如下:

public function sessionx(Request $request){
$request->session()->reflash();
$message = session('message');
echo $message;
}

这样不管怎么刷新Session数据始终有效。此外还可以指定哪些Session数据有效:

$request->session()->keep(['message']);

Laravel 5.1 中 Session 数据存储、访问、删除及一次性Session实例教程的更多相关文章

  1. Memcached存Session数据、访问安全性、使用场景总结(3)

    最近做了一个单点登录SSO,登陆后的凭证放到Memcached令牌放到Cookies:但是用户经常掉线,开发环境和测试却没有这个问题,最后从Memcached找到原因. Memcached概念.作用. ...

  2. 67.Android中的数据存储总结

    转载:http://mp.weixin.qq.com/s?__biz=MzIzMjE1Njg4Mw==&mid=2650117688&idx=1&sn=d6c73f9f04d0 ...

  3. Android中的数据存储

    Android中的数据存储主要分为三种基本方法: 1.利用shared preferences存储一些轻量级的键值对数据. 2.传统文件系统. 3.利用SQLite的数据库管理系统. 对SharedP ...

  4. Android中的数据存储(二):文件存储 2017-05-25 08:16 35人阅读 评论(0) 收藏

    文件存储 这是本人(菜鸟)学习android数据存储时接触的有关文件存储的知识以及本人自己写的简单地demo,为初学者学习和使用文件存储提供一些帮助.. 如果有需要查看SharedPreference ...

  5. 【solr】SolrCloud中索引数据存储于HDFS

    SolrCloud中索引数据存储于HDFS 本人最近使用SolrCloud存储索引日志条件,便于快速索引,因为我的索引条件较多,每天日志记录较大,索引想到将日志存入到HDFS中,下面就说说怎么讲sol ...

  6. Java基础知识强化之IO流笔记45:IO流练习之 把集合中的数据存储到文本文件案例

    1. 把集合中的数据存储到文本文件案例:    需求:把ArrayList集合中的字符串数据存储到文本文件 ? (1)分析:通过题目的意思我们可以知道如下的一些内容,ArrayList集合里存储的是字 ...

  7. 安卓中的数据存储方式以及ContentProvider的简单介绍

    1.介绍android的数据存储方式 File存储 sharedPrefrence存储方式 conmtentprovider sqlitedatabase 网络存储   2.请介绍下ContentPr ...

  8. 怎样实现IOS开发中的数据存储方式

    iOS 开发中,一般有如下几种数据存储方式.需要根据具体的业务场景,选择 合适的数据存储方式. (1)  用户默认设置 – 这种情况通常不需要用户干预,如游戏通关信息,Video 播放记录,或者 Ap ...

  9. IOS中的数据存储方式,特点,使用情况

    数据存储的核心都是写文件,主要有四种持久化方式:属性列表(Plist),对象序列化,SQLite数据库,CoreData. 存储Plist: 键值进行存储,不能存储对象.对象需要序列化编码才能写入文件 ...

随机推荐

  1. 构建NCBI本地BLAST数据库 (NR NT等) | blastx/diamond使用方法 | blast构建索引 | makeblastdb

    参考链接: FTP README 如何下载 NCBI NR NT数据库? 下载blast:ftp://ftp.ncbi.nlm.nih.gov/blast/executables/blast+ 先了解 ...

  2. 从mysql数据库删除重复记录只保留其中一条

    这两天做了一个调用第三方接口的小程序,因为是实时更新数据,所以请求接口的频率就很高,这样有时会出现往数据库插入重复的数据,对数据库造成压力也不方便管理,因为要通过原生sql语句,解决数据库的去重问题. ...

  3. h1042 N!大数乘int

    计算10000以内某个数的阶乘,即大数乘以int,考虑到一个int存一个数位过于繁琐且浪费空间,采用万进制 一个int存四个位数,但注意除了最高位,其他位不够四位数时要加上前导0凑够四位: 例1234 ...

  4. HDU-2829 Lawrence (DP+四边形不等式优化)

    题目大意:有n个敌方军火库呈直线排列,每个军火库有一个值vi,并且任意相邻的两个库之间都有通道相连.对于任意一条连起来的军火库链,它对我方的威胁可以用函数w(i,j)表示为:w(i,j)=vi*sum ...

  5. UVA-1663 Purifying Machine (最大匹配数)

    题目大意:每一个01串中最多含有一个‘*’,‘*’既可表示0也可表示1,给出一些等长的这样的01串,问最少能用多少个这样的串表示出这些串.如:000.010.0*1表示000.010.001.011, ...

  6. ShardedJedis的使用

    假定有2个 redis 服务实例(A和B)在运行,在客户端进行 set 操作: set a0 xxx set a1 xxx set a2 xxx set a3 xxx 我们希望a0, a1, a2, ...

  7. spring boot学习(十三)SpringBoot缓存(EhCache 2.x 篇)

    SpringBoot 缓存(EhCache 2.x 篇) SpringBoot 缓存 在 Spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManag ...

  8. java反编译工具eclipse插件jad的使用

    https://www.cnblogs.com/zhikou/p/8098137.html 这边文章主要介绍如何使用Eclipse的插件jad进行反编译,在查看一些jar包里面的class文件时,就可 ...

  9. SQL Server 调优系列进阶篇 - 如何维护数据库索引

    前言 上一篇我们研究了如何利用索引在数据库里面调优,简要的介绍了索引的原理,更重要的分析了如何选择索引以及索引的利弊项,有兴趣的可以点击查看. 本篇延续上一篇的内容,继续分析索引这块,侧重索引项的日常 ...

  10. 快速切题 cf118A

    这教导人们一定要看题,要看题,元音包含了‘y’,完毕,要看题啊 #include <cstring> #include <cstdio> #include <cctype ...