徐善通的随笔

千里之行, 始于足下



php session之存储在redis的方法


安装redis

  1. 安装redis https://www.xstnet.com/article-50.html
  2. 安装phpredis扩展 https://www.xstnet.com/article-42.html

设置php.ini

  1. 打开php.ini, 查找session.save_handler, 将其值设置为 redis
  2. 查找session.save_path, 将其设置为"tcp://127.0.0.1:6379″, 注意要加双引号

设置为

// 如果有密码
session.save_path = "tcp://127.0.0.1:6379?auth=youpwd″
// 如果没有密码
session.save_path = "tcp://127.0.0.1:6379

整体如下

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?auth=youpwd″

修改完记得重载nginx, 重启php-fpm

上图
alt

如果有密码但是没有设置的话, 会报下面的错误

Warning: session_start(): Failed to read session data: redis (path: tcp://127.0.0.1:6379)
Fatal error: Uncaught RedisException: NOAUTH Authentication required

其他参数

使用tcp://127.0.0.1:6379不仅可以传auth参数, 还可以传下列参数

  • weight(整数):主机的权重与其他主机的权重相比较,以便在多个主机上自定义会话分配。如果主机A的重量是主机B的两倍,它将获得两倍的会话数量。在该示例中,host1存储所有会话的20%(1 /(1 + 2 + 2)),而host2和-
    host3每个存储40%(2 /(1 + 2 + 2))。目标主机在会话开始时一劳永逸地确定,并且不会更改。默认权重为1。
  • timeout(float):redis主机的连接超时,以秒为单位。如果主机在该时间内无法访问,则会话存储将不可用于客户端。默认超时非常高(86400秒)。
  • persistent(整数,应该是1或0):定义是否应该使用持久连接。(实验设定)
  • prefix(字符串,默认为“PHPREDIS_SESSION:”):用作存储会话的Redis密钥的前缀。密钥由前缀后跟会话ID组成。
  • auth(字符串,默认为空):用于在发送命令之前对服务器进行身份验证。
  • database(整数):选择不同的数据库。

同时还支持传入多个redis服务器, 使用英文逗号分割, 如下:

session.save_path = "tcp://host1:6379?weight=1&database=1, tcp://host2:6379?weight=2&timeout=2.5, tcp://host3:6379?weight=2&read_timeout=2.5"

不能修改php.ini? 试试ini_set函数

ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');

测试

// 设置显示错误气提示
ini_set('display_errors', true);
error_reporting(E_ALL);

// 配置session 存储于redis
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379?auth=123456789');

session_start();
// 这个就是redis中存储数据的key, 
// redis用session_id作为key 并且是以string的形式存储
// php向redis写入数据时是已经序列化之后的数据
$redisKey = 'PHPREDIS_SESSION:' . session_id();

// SESSION 赋值测试
$_SESSION['message'] = "Hello, I'm in redis";
$_SESSION['arr'] = [1, 2, 3, 4, 5, 6];

echo $_SESSION['message'] , '<br/>';
echo 'Redis key =    ' . $redisKey . '<br/>';

echo '以下是从Redis获取的数据', '<br/>';
// 取数据
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('123456789');

echo $redis->get($redisKey);

输出

Hello, I'm in redis
Redis key = PHPREDIS_SESSION:u14hqvsvcnr6m0n2qt4eh53642
以下是从Redis获取的数据
message|s:19:"Hello, I'm in redis";arr|a:6:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;}

查看当前key

[xstnet~]$ redis-cli 
127.0.0.1:6379> auth 123456789
OK
127.0.0.1:6379> get PHPREDIS_SESSION:u14hqvsvcnr6m0n2qt4eh53642
"message|s:19:\"Hello, I'm in redis\";arr|a:6:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;}"
127.0.0.1:6379> TTL PHPREDIS_SESSION:u14hqvsvcnr6m0n2qt4eh53642
(integer) 1417
127.0.0.1:6379>

可以看到, 已经赋值成功了, 这里使用TTL显示获取剩余时间正好是session默认的1440秒减去我们操作的时间得到的结果

关于 session.save_handler和session.save_path

  • session.save_handler: 定义了来存储和获取与会话关联的数据的处理器的名字。默认为 files
  • session.save_path: 定义了传递给存储处理器的参数。如果选择了默认的 files 文件处理器,则此值是创建文件的路径。默认为 /tmp

session_path 指令还有一个可选的 N 参数来决定会话文件分布的目录深度。例如,设定为 '5;/tmp' 将使创建的会话文件和路径类似于 /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If。要使用 N 参数,必须在使用前先创建好这些目录。在 ext/session 目录下有个小的 shell 脚本名叫 mod_files.sh,windows 版本是 mod_files.bat 可以用来做这件事。此外注意如果使用了 N 参数并且大于 0,那么将不会执行自动垃圾回收,更多信息见 php.ini。另外如果用了 N 参数,要确保将 session.save_path 的值用双引号 "quotes" 括起来,因为分隔符分号( ;)在 php.ini 中也是注释符号。

官方提示

文件储存模块默认使用 mode 600 创建文件。通过 修改可选参数 MODE 来改变这种默认行为: N;MODE;/path ,其中 MODE 是 mode 的八进制表示。 MODE 设置不影响进程的掩码(umask)。

Caution
使用以上描述的可选目录层级参数 N 时请注意,对于绝大多数站点,大于1或者2的值会不太合适——因为这需要创建大量的目录:例如,值设置为 3 需要在文件系统上创建 64^3 个目录,将浪费很多空间和 inode。
仅仅在绝对肯定站点足够大时,才可以设置 N 大于2。

查看更多信息https://www.php.net/manual/zh/session.configuration.php#ini.session.save-handlerf


作者: 徐善通
地址: https://www.xstnet.com/article-108.html
声明: 除非本文有注明出处,否则转载请注明本文地址


我有话说



最新回复


正在加载中....

Copyrights © 2016-2019 醉丶春风 , All rights reserved. 皖ICP备15015582号-1