stefangabos / zebra_session
PHP默认会话处理程序的即时替代品,将会话数据存储在MySQL数据库中,提供更好的性能、更安全的保护以及防止会话固定和会话劫持
Requires
- php: >=5.5.2
Requires (Dev)
- phpstan/phpstan: ^1.12
- squizlabs/php_codesniffer: ^3.10
README
Zebrasession 
PHP默认会话处理程序的即时替代品,将会话数据存储在MySQL数据库中,提供更好的性能、更安全的保护以及防止会话固定和会话劫持
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)会不考虑其他进程和会话数据的状态而访问会话数据。请求的运行时间由每个进程彩色区域的长度表示(实际的运行时间并不重要,只有相对的开始时间和持续时间)。
在上面的示例中,无论P2和P3如何更改会话数据,只有P1所做的更改会被反映在会话中,因为它们是最后写入的。当使用锁定时,进程可以在读取之前启动,请求会话数据的锁定,然后一旦获得对其的独占访问权,就可以获取会话的一致性读取。在以下图中,所有读取都在写入之后发生
进程执行是交错的,但会话数据的访问是序列化的。在进程请求会话锁和读取会话之间等待锁释放的这段时间内,进程正在等待。这意味着您的会话数据将保持一致,但这也意味着当P2和P3等待获得锁的机会时,没有任何事情发生。如果所有请求都更改或写入会话数据,这可能并不重要,但如果P2只需要读取会话数据(例如获取登录标识符),那么它就毫无理由地被耽搁了。
因此,最终,这不是最佳解决方案,但总比没有好。最佳解决方案可能是按变量锁定。您可以在Andy Bakun的文章中阅读关于所有这些的非常详细的介绍:Ajax和PHP会话中的竞态条件。
感谢Michael Kliewe将此问题引起我的注意!
功能
-
作为PHP默认会话处理函数的包装器,但它将会话数据存储在MySQL数据库中,而不是存储在平面文件中,提供更好的安全性和更好的性能
-
它是PHP默认会话处理程序的即插即用和无缝替代品:使用库之前和之后将使用相同的方式使用PHP会话;您不需要更改任何现有代码!
-
无缝集成PDO(如果您使用PDO),但不使用PDO也能完美运行
-
实现了行锁定,确保在多个并发AJAX请求的场景中正确处理数据
-
因为会话数据存储在数据库中,该库为跨多个Web服务器(使用负载均衡器或轮询DNS)扩展的应用程序提供了一个解决方案
-
拥有出色的文档
-
代码注释详细,当PHP的错误报告级别设置为E_ALL时不会生成警告/错误/通知
📔 文档
查看出色的文档!
🎂 支持此项目的发展
您的支持意义重大,它激励我继续从事开源项目。
如果您喜欢此项目,请通过点击页面顶部的星号按钮来⭐它。
如果您慷慨大方,可以通过PayPal捐赠给我咖啡,或者您可以成为赞助商。
无论如何 - 谢谢! 🎉
要求
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!