簡體   English   中英

PHP7.4 Session 存儲上 Redis 問題

[英]PHP7.4 Session storage on Redis issue

我將 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()也適用於應用程序的 scope。

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 服務

但在您的情況下,您已經提到您需要 PHP session 僅針對特定應用程序由 Redis 處理。 所以我很好奇這是否可以實現。 為此,我使用了默認的 php.ini 設置和session.save_handler = filessession.save_path注釋掉。 所以要實現這個session_set_save_handler function 應該使用https://www.php.net/manual/en/function.session-set-save-handler.ZE1BFD762321E409CEEZ4AC0B

session_set_save_handler() 設置用戶級 session 存儲函數,用於存儲和檢索與 session 關聯的數據。 當首選 PHP 會話提供的存儲方法以外的存儲方法時,這是最有用的,例如將 session 數據存儲在本地數據庫中。

我還使用本指南來完成一個完整的工作示例(顯然這不應該在生產中使用) 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 class 會將 session 處理程序設置為 Redis。 這帶有一個小測試,在連續的頁面重新加載時將創建並增加一個計數器。 您可以連接到 redis 服務器並運行 flushall 命令並觀察計數器如何重置。

一提是啟用 php-redis 擴展。

$ php -m | grep redis 

應該顯示“redis”。 如果沒有,可以像這樣安裝(在 Ubuntu 中):

sudo apt-get install php-redis

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM