【问题标题】:How to unserialize PHP sessions from Redis?如何从 Redis 反序列化 PHP 会话?
【发布时间】:2018-08-30 16:20:18
【问题描述】:

如何反序列化存储在 Redis 中的 PHP 会话?我需要从 websocket 服务器获取会话变量。无法使用session_start()

unserialize($this->redis->get('PHPREDIS_SESSION:'.$session_id));

错误

unserialize():319 字节偏移量 0 处出错

Redis

apt-get install php7.0-redis

127.0.0.1:6379> get PHPREDIS_SESSION:tmcls6v5n157q4kva4795hv4j1
"time_user_offset|i:0;activity_time|i:1535643086;ltype|s:6:\"CLIENT\";cid|i:1;uid|i:1;uid_admin|i:1;is_suspended|i:0;is_timeout_time|i:0;is_trial|i:0;is_full|i:1;lid|i:197240;is_ready|i:1;currency_name|s:3:\"DKK\";set_reverse_sign|i:0;bid|i:1;block_name|s:14:\"text\";addon_crm|i:1;suid|i:0;is_supporter|i:0;tmp|i:0;"

php.ini

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

更新

会话在 PHP 中工作正常,所以这不是错误

【问题讨论】:

  • 我们不是在 30 分钟前做这个问题吗?
  • @RiggsFolly 我们读了,但 cmets 中的每个人(包括我自己)都没有正确阅读(尤其是编辑)
  • 正如男人所说的:)

标签: php redis


【解决方案1】:

PHP 不使用其标准序列化格式来存储会话。类似,但unserialize 不知道怎么读。如果您已使用 php.ini 中的 session.save_handler 设置将 Redis 配置为会话存储,那么它将使用默认的 serialize_handler 值,并使用该序列化格式存储您的会话。

幸运的是,您仍然可以在 PHP 中手动解码 - 您只需使用 session_decode 代替。这将使用您传递给它的数据(在本例中是来自 Redis 的字符串)填充 $_SESSION 超全局变量,然后您可以像在任何其他脚本中一样引用它。

请注意,如果您写回服务器 B 上的会话,它不会被保存回 Redis(这可能很明显,但以防万一)。

服务器 A:

<?php
session_start();
$_SESSION['foo'] = 'bar';

服务器 B:

<?php
session_start();

$data = $this->redis->get('...');
session_decode($data);

echo $_SESSION['foo']; // bar

最后,为了清楚起见 - 这不是 Redis 或 Redis 会话处理程序的问题 - 如果您从文件系统读取会话并尝试使用 unserialize 对其进行解码,则会遇到同样的问题。问题只是序列化格式,而不是存储。

【讨论】:

  • 你的解决方案 B 给出了bool(true)
  • 啊.. $_SESSION 得到了数据 :)
  • 是的,session_decode 有点烦人——它不返回数据,它只是填充会话超全局。但如果这对你有用,那么这不是问题。
【解决方案2】:

我参加聚会有点晚了,但我找到了解决办法。

名为php 的默认php 会话序列化程序的问题在于它使用的格式与公开的unserialize() 函数接受的序列化格式不同。你经历过。

但是 PHP 有比 php 更多的内置序列化程序。 php_serialize 使用通过serialize()unserialize() 公开的格式。 (从什么时候开始快速搜索并没有发现。)

如果您设置session.serialize_handler = php_serialize,您的代码将起作用。

如果您要处理大量数据,我建议您使用igbinary extension。 igbinary 一个经过验证的序列化程序,它使用更高效的二进制格式,您也可以对其进行反序列化。

$ pecl install igbinary
$ echo 'session.serialize_handler = igbinary' >> your/php.ini
igbinary_unserialize($this->redis->get('PHPREDIS_SESSION:'.$session_id));

【讨论】:

    猜你喜欢
    • 2013-10-05
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 2011-12-26
    • 1970-01-01
    • 2015-08-28
    • 2015-03-31
    相关资源
    最近更新 更多