Session 您所在的位置:网站首页 开启session会话 Session

Session

2023-08-20 04:19| 来源: 网络整理| 查看: 265

本文档最新版为 10.x,旧版本可能放弃维护,推荐阅读最新版! HTTP 会话机制 简介 配置驱动程序先决条件 使用 Session 获取数据存储数据闪存数据删除数据重新生成 Session ID Session Blocking添加自定义 Session 驱动 实现驱动注册驱动

简介

由于 HTTP 驱动的应用程序是无状态的,Session 提供了一种在多个请求之间存储有关用户信息的方法,Laravel 通过同一个可读性强的 API 处理各种自带的后台驱动程序。支持诸如比较热门的 Memcached, Redis 和数据库。

配置

Session 的配置文件存储在 config/session.php 文件中。请务必查看此文件中对于你而言可用的选项。默认情况下,Laravel 为绝大多数应用程序配置的 Session 驱动为 file 。在生产环境中,你可以考虑使用 memcached 或 redis 驱动,让 Session 的性能更加出色。

Session driver 的配置预设了每个请求存储 Session 数据的位置。Laravel 自带了几个不错而且开箱即用的驱动:

file - 将 Session 存储在 storage/framework/sessions 中。cookie - Sessions 被存储在安全加密的 cookie 中。database - Sessions 被存储在关系型数据库中。memcached / redis - Sessions 被存储在基于高速缓存的存储系统中。array - Sessions 存储在 PHP 数组中,但不会被持久化。

技巧:数组驱动一般用于 测试 并且防止存储在 Session 中的数据被持久化。

驱动程序先决条件 数据库

使用 database 作为 Session 驱动时,你需要创建一张包含 Session 各项数据的表。以下是使用 Schema 建表的例子:

Schema::create('sessions', function ($table) { $table->string('id')->unique(); $table->foreignId('user_id')->nullable(); $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->text('payload'); $table->integer('last_activity'); });

你可以使用 Artisan 命令 session:table 来生成此迁移:

php artisan session:table php artisan migrate Redis

Laravel 在使用 Redis 作为 Session 驱动之前,需要安装 Redis 的 PHP 扩展或者通过 Composer 安装 predis/predis 扩展包 (~1.0)。Redis 的详细配置信息参考 Laravel Redis 文档。

技巧:在 session 配置文件中,connection 选项可用于指定会话使用哪个 Redis 连接。

使用 Session

获取数据

Laravel 中处理 Session 数据有两种主要方法:全局辅助函数session和通过一个Request实例。首先,我们来看看通过控制器方法类型提示一个Request实例来访问 session。控制器方法依赖项会通过 Laravel 服务容器 实现自动注入:

session()->get('key'); // } }

当你从 Session 获取值时,你还可以传递一个默认值作为get方法的第二个参数。如果 Session 中不存在指定的键,便会返回这个默认值。若传递一个闭包作为get方法的默认值,并且所请求的键并不存在时,get方法将执行闭包并返回其结果:

$value = $request->session()->get('key', 'default'); $value = $request->session()->get('key', function () { return 'default'; }); 全局辅助函数 Session

你也可以使用全局的 PHP 辅助函数session来获取和存储 Session 数据。 使用单个字符串类型的值作为参数调用辅助函数session时,它会返回该字该符串对应的 Session 键的值。当使用一个键值对数组作为参数调用辅助函数session时,传入的键值将会存储在 Session 中:

Route::get('home', function () { // 获取 session 中的一条数据... $value = session('key'); // 指定默认值 $value = session('key', 'default'); // 在 Session 中存储一条数据... session(['key' => 'value']); });

技巧:通过 HTTP 请求实例操作 Session 与使用全局辅助函数session两者之间并没有实质上的区别。这两种方法都可以通过所有测试用例中可用的assertSessionHas方法进行 测试 。

获取所有 Session 数据

如果你想获取 session 中的所有数据,可以使用 all 方法:

$data = $request->session()->all(); 判断 Session 中是否存在某个值

要确定 Session 中是否存在某个值,可以使用has方法。如果该值存在且不为null,那么has方法会返回true:

if ($request->session()->has('users')) { // }

要确定 Session 中是否存在某个值,即使其值为null,也可以使用exists方法。如果值存在,则exists方法返回true:

if ($request->session()->exists('users')) { // }

存储数据

想要存储数据到 Session,你可以使用 put 方法,或者使用辅助函数 session:

// 通过请求实例... $request->session()->put('key', 'value'); // 通过全局辅助函数... session(['key' => 'value']); 保存数据到 Session 数组中

push 方法可以将一个新的值添加到 Session 数组内。例如,假设 user.teams 这个键是包括团队名称的数组,你可以这样将一个新的值加入到数组中:

$request->session()->push('user.teams', 'developers'); 检索 & 删除一条数据

pull 方法可以只使用一条语句就从 Session 中检索并删除一条语句:

$value = $request->session()->pull('key', 'default');

闪存数据

有时候你可能想在 Session 中保存数据用于下一次请求,这时你可以使用 flash 方法。使用这个方法保存在 Session 中的数据,只会保留到下一个 HTTP 请求到来之前,然后就会被删除。闪存数据主要用于短期的状态消息:

$request->session()->flash('status', 'Task was successful!');

如果你需要在更多的请求中使用到该一次性数据,你可以使用 reflash 方法,该方法会将所有一次性请求保留到下一次请求。如果你想保存一次性数据,你可以用 keep 方法:

$request->session()->reflash(); $request->session()->keep(['username', 'email']);

删除数据

forget 方法会从 Session 中删除指定数据,如果想从 Session 中删除所有数据,可以使用 flush 方法:

// 删除单个值... $request->session()->forget('key'); // 删除多个值... $request->session()->forget(['key1', 'key2']); $request->session()->flush();

重新生成 Session ID

重新生成 session ID 通常是为了防止恶意用户利用 session fixation 对你的应用进行攻击。

如果你使用了内置的 LoginController,Laravel 会自动重新生成身份认证中的 Session ID。否则,你需要手动使用 regenerate 方法重新生成 Session ID。

$request->session()->regenerate();

Session 阻塞

注意:要利用会话阻止,您的应用程序必须使用支持 atomic locks 的缓存驱动。 当前,这些缓存驱动包括 memcached,dynamodb,redis 和 database 驱动程序。 另外,您不能使用cookie 驱动。

默认情况下,Laravel允许使用同一 session 的请求并发执行。 例如,如果您使用JavaScript HTTP 库向应用程序发出两个HTTP请求,则它们将同时执行。 对于许多应用程序来说,这不是问题。 但是,在一小部分应用程序中可能会丢失 session 数据,这些应用程序会向两个不同的应用程序端点同时发出请求,这两个端点都将数据写入 session。

为了处理这种情况,Laravel 允许您限制指定会话的并发请求。 首先,您可以简单地在定义路由时调用 block 方法。 在这个例子中,进入到 /profile 端点的请求将添加会话锁。 在会话锁期间,/ profile 或 / order 端点共享相同 session ID 的任何请求都将等待第一个请求执行完成,然后再继续执行:

Route::post('/profile', function () { // })->block($lockSeconds = 10, $waitSeconds = 10) Route::post('/order', function () { // })->block($lockSeconds = 10, $waitSeconds = 10)

block方法接受两个可选参数。 第一个参数是会话锁在释放之前应保持的最大秒数。 当然,如果请求在此时间之前完成执行,则锁将更早释放。

第二个参数是请求尝试获得会话锁时应等待的秒数。 如果请求无法在给定的秒数内获得会话锁,则将抛出 Illuminate\Contracts\Cache\LockTimeoutException。

如果这些参数都未传递,那么将最多获得10秒的锁定,而尝试获得锁定的请求将最多等待10秒:

Route::post('/profile', function () { // })->block()

添加自定义 Session 驱动

实现驱动

你自定义的 Session 驱动必须实现 SessionHandlerInterface 接口。这个接口包含了一些我们需要实现的简单方法。下面是 MongoDB 实现的大概流程示例:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有