我将 PHP 版本从 7.1 升级到 7.2、7.3、7.4。
升级后,我面临 Redis 上的 session 存储问题。
我正在尝试配置我的应用程序
Php 7.4
Php-redis 5.2.1
Yii 2.0.15
Nginx 1.14.0 (Ubuntu)
Ubuntu 18.04
在我的应用程序配置中, 我已经设置了
session_save_path("tcp://127.0.0.1:6379?auth=admin123&prefix=AT_R_");
当我尝试运行该应用程序时,出现以下错误:
[error] 21728#21728: *1081 FastCGI sent in stderr: "PHP message: yii\base\InvalidArgumentException: Session save path is not a valid directory: tcp://127.0.0.1:6379?auth=admin123&prefix=AT_R_ in /var/www/php-aertrip/vendor/yiisoft/yii2/web/Session.php:352
奇怪的是, 相同的代码设置在 Php 7.1 上运行完美,但不适用于 7.2、7.3 以及现在的 7.4。
我找不到任何理由使其不起作用。请提出此问题的可能原因。
感谢任何帮助..提前致谢。
最佳答案
LE:
因此,实际上使用 ini_set()
也适用于应用程序的范围。
ini_set('session.save_handler','redis');
ini_set('session.save_path','tcp://127.0.0.1:6379?auth=admin123&prefix=AT_R_');
--
此处为 Ubuntu 18.04/PHP 7.4.9。 我刚刚将 PHP 设置为与 Redis 作为 session 处理程序一起运行。 就我而言,我只是采用简单的方法来更改 php.ini 中的 PHP 设置
session.save_handler = redis
session.save_path = "tcp://10.0.0.1:6379?auth=secretpass123"
这里提到一些:
- 密码(如果有)必须经过 URL 编码
- 每次编辑 php.ini 文件后重新启动 Apache/FPM 服务
但就您的情况而言,您提到您只需要 Redis 为特定应用程序处理 PHP session 。所以我很好奇这是否可以实现。
为此,我使用了默认的 php.ini 设置,并注释掉了 session.save_handler = files
和 session.save_path
。
因此,要实现此目的,应使用 session_set_save_handler
函数 https://www.php.net/manual/en/function.session-set-save-handler.php
session_set_save_handler() sets the user-level session storage functions which are used for storing and retrieving data associated with a session. This is most useful when a storage method other than those supplied by PHP sessions is preferred, e.g. storing the session data in a local database.
我还使用本指南来获得完整的工作示例(显然这不应该在生产中使用)https://developpaper.com/how-to-use-redis-to-save-user-session-details/
<?php
class SessionManager
{
private $redis;
private $sessionSavePath;
private $sessionName;
private $session_expiretime = 60;
public function __construct()
{
$this->redis = new Redis();// Create phpredis instance
$this->redis->connect('10.0.0.1', 6379); // connect redis
$this->redis->auth("secretpass123"); // authorization
session_set_save_handler(
array($this, "open"),
array($this, "close"),
array($this, "read"),
array($this, "write"),
array($this, "destroy"),
array($this, "gc")
);
if (!isset($_SESSION)) session_start();
}
public function open($path, $name)
{
return true;
}
public function close()
{
return true;
}
public function read($id)
{
$value = $this->redis->get($id); // Get the specified record in redis
if ($value) {
return $value;
} else {
return '';
}
}
public function write($id, $data)
{
if ($this->redis->set($id, $data)) {
// stored with session ID as the key
$this->redis->expire($id, $this->session_expiretime); // Set the expiration time of data in redis, that is, session expiration time
return true;
}
return false;
}
public function destroy($id)
{
if ($this->redis->delete($id)) {// delete the specified record in redis
return true;
}
return false;
}
public function gc($maxlifetime)
{
return true;
}
public function __destruct()
{
session_write_close();
}
}
$handler = new SessionManager();
if (isset($_SESSION['test'])) {
echo ++$_SESSION['test'];
} else {
$_SESSION['test'] = 0;
echo 'not set - 0';
}
实例化 SessionManager 类会将 session 处理程序设置为 Redis。这附带了一个小测试,在连续的页面重新加载时将创建并增加一个计数器。 您可以连接到redis服务器并运行flushall命令并观察计数器如何重置。
值得一提的是启用 php-redis 扩展。
$ php -m | grep redis
应显示“redis”。 如果没有,可以像这样安装(在 Ubuntu 中):
sudo apt-get install php-redis
关于PHP7.4 Redis上的Session存储问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61898235/