stefangabos/zebra_session

PHP默认会话处理程序的即时替代品,将会话数据存储在MySQL数据库中,提供更好的性能、更安全的保护以及防止会话固定和会话劫持

4.1.0 2024-09-08 17:27 UTC

This package is auto-updated.

Last update: 2024-09-09 18:11:19 UTC


README

zebrajs

Zebrasession  Tweet

PHP默认会话处理程序的即时替代品,将会话数据存储在MySQL数据库中,提供更好的性能、更安全的保护以及防止会话固定和会话劫持

Latest Stable Version Total Downloads Monthly Downloads Daily Downloads License

PHP中的会话支持是一种在网站页面后续访问中保留信息(变量)的方式。与cookie不同,变量不会存储在用户的计算机上。相反,仅在访问者的计算机上的cookie中存储一个会话标识符,它与服务器上实际存储的会话数据相匹配,并通过$_SESSION超级全局变量供我们使用。会话数据在我们打开会话时检索,通常在每个页面的开始。

默认情况下,会话数据存储在服务器上的平面文件中,每个会话一个。这种情况下的问题是,随着会话目录中会话文件数量的增加(取决于服务器操作系统能够处理大量文件的目录的能力),性能成比例下降。另一个问题是,会话文件通常存储在一个对所有人可读的位置,这在使用共享主机时带来了安全风险。

这就是Zebrasession发挥作用的地方——一个作为PHP默认会话处理程序的即时替代品的PHP库,但它不是将会话数据存储在平面文件中,而是将它们存储在MySQL数据库中,提供更好的安全性和更好的性能。

Zebrasession也是针对跨多个Web服务器(使用负载均衡器或循环DNS)扩展的应用程序的解决方案,其中用户的会话数据需要可用。将会话存储在数据库中使它们对所有服务器都可用!

支持"闪存数据" - 仅在下一个服务器请求中可用的会话变量,并在之后自动删除。通常用于信息或状态消息(例如:“数据已成功更新”)。

这个类受到了John Herren的代码的启发,该代码来自Trick out your session handler文章(现在仅在Internet Archive中可用)和Chris Shiflett的书Essential PHP Security第8章,共享主机,第78-80页。

Zebra Session的代码注释详细,并且在PHP的错误报告级别设置为E_ALL时不会生成警告/错误/通知。

从版本2.0开始,Zebra Session实现了行锁定,确保在多个并发AJAX请求的场景下正确处理数据。

摘自Race Conditions with Ajax and PHP Sessions,Andy Bakun撰写的优秀文章

当不使用锁定时,多个请求(在这些图中表示为进程P1、P2和P3)会不考虑其他进程和会话数据的状态而访问会话数据。请求的运行时间由每个进程彩色区域的长度表示(实际的运行时间并不重要,只有相对的开始时间和持续时间)。

Session access without locking

在上面的示例中,无论P2和P3如何更改会话数据,只有P1所做的更改会被反映在会话中,因为它们是最后写入的。当使用锁定时,进程可以在读取之前启动,请求会话数据的锁定,然后一旦获得对其的独占访问权,就可以获取会话的一致性读取。在以下图中,所有读取都在写入之后发生

Session access without locking

进程执行是交错的,但会话数据的访问是序列化的。在进程请求会话锁和读取会话之间等待锁释放的这段时间内,进程正在等待。这意味着您的会话数据将保持一致,但这也意味着当P2和P3等待获得锁的机会时,没有任何事情发生。如果所有请求都更改或写入会话数据,这可能并不重要,但如果P2只需要读取会话数据(例如获取登录标识符),那么它就毫无理由地被耽搁了。

因此,最终,这不是最佳解决方案,但总比没有好。最佳解决方案可能是按变量锁定。您可以在Andy Bakun的文章中阅读关于所有这些的非常详细的介绍:Ajax和PHP会话中的竞态条件

感谢Michael Kliewe将此问题引起我的注意!

功能

  • 作为PHP默认会话处理函数的包装器,但它将会话数据存储在MySQL数据库中,而不是存储在平面文件中,提供更好的安全性和更好的性能

  • 它是PHP默认会话处理程序的即插即用和无缝替代品:使用库之前和之后将使用相同的方式使用PHP会话;您不需要更改任何现有代码!

  • 无缝集成PDO(如果您使用PDO),但不使用PDO也能完美运行

  • 实现了行锁定,确保在多个并发AJAX请求的场景中正确处理数据

  • 因为会话数据存储在数据库中,该库为跨多个Web服务器(使用负载均衡器或轮询DNS)扩展的应用程序提供了一个解决方案

  • 拥有出色的文档

  • 代码注释详细,当PHP的错误报告级别设置为E_ALL时不会生成警告/错误/通知

📔 文档

查看出色的文档

🎂 支持此项目的发展

您的支持意义重大,它激励我继续从事开源项目。
如果您喜欢此项目,请通过点击页面顶部的星号按钮来⭐它。
如果您慷慨大方,可以通过PayPal捐赠给我咖啡,或者您可以成为赞助商。
无论如何 - 谢谢! 🎉

Star it on GitHub Donate

要求

PHP 5.5.2+,已激活mysqli扩展,MySQL 4.1.22+

安装

您可以通过Composer进行安装

# get the latest stable release
composer require stefangabos/zebra_session

# get the latest commit
composer require stefangabos/zebra_session:dev-master

或者您可以手动安装:下载最新版本,解压,然后将其包含到您的项目中

require_once 'path/to/Zebra_Session.php';

安装MySQL表

注意一个名为 install 的目录,其中包含一个名为 session_data.sql 的文件。此文件包含用于创建由类存储会话数据的表的 SQL 代码。使用您首选的 MySQL 管理器(如 phpMyAdmin 或出色的 Adminer)将 SQL 代码导入或执行到您选择的数据库中。

使用方法

请注意,此类假设存在对 MySQL 数据库的活跃连接,并且它不会尝试创建一个连接!

<?php
// first, connect to a database containing the sessions table
// either by something similar to
//
// $link = mysqli_connect(host, username, password, database);
//
//  or by using PDO
//
//  try {
//      $link = new PDO(
//      'mysql:host=' . $host . ';dbname=' . $database . ';charset=utf8mb4', $username, $password, array(
//         PDO::ATTR_ERRMODE   =>  PDO::ERRMODE_EXCEPTION,
//     ));
// } catch (\PDOException $e) {
//     throw new \PDOException($e->getMessage(), (int)$e->getCode());
// }

// include the Zebra_Session class
// (you don't need this if you are using Composer)
require 'path/to/Zebra_Session.php';

// instantiate the class
// this also calls session_start()
$session = new Zebra_Session($link, 'sEcUr1tY_c0dE');

// from now on, use sessions as you would normally
// this is why it is called a "drop-in replacement" :)
$_SESSION['foo'] = 'bar';

// data is in the database!