简体   繁体   中英

PHP7.4 Session storage on Redis issue

I upgraded PHP version from 7.1 to 7.2, 7.3, 7.4.

And after updgrading I am facing issue with Session storage on Redis.

I am trying to configure my application with

Php 7.4

Php-redis 5.2.1

Yii 2.0.15

Nginx 1.14.0 (Ubuntu)

Ubuntu 18.04

In my application configuration, i have set

session_save_path("tcp://127.0.0.1:6379?auth=admin123&prefix=AT_R_");

when i try to run the application, i am getting the following error:

[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

The strange thing is, the same code settings with Php 7.1 runs perfectly , but does not work with 7.2, 7.3 and now at 7.4.

I am not able to find any reason for this to not work. Kindly suggest what might be the cause of this issue.

Any Help is appreciated.. Thanks in advance.

LE: So actually using ini_set() also works in the scope of an app.

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 here. I've just setup PHP to run with Redis as a session handler. In my case I've just went for the simple approach to change the PHP settings in php.ini

session.save_handler = redis
session.save_path = "tcp://10.0.0.1:6379?auth=secretpass123"

A few mentions here:

  • the password (if any) has to be URL encoded
  • restart Apache / FPM service after every edit in the php.ini file

BUT in your case, you've mentioned that you need the PHP session handled by Redis only for a specific app. So I was curious if that can be achieved. For that I've used the default php.ini settings with session.save_handler = files and the session.save_path commented out. So to achieve this the session_set_save_handler function should be used 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, eg storing the session data in a local database.

I've also used this guide to come to a full working example (obviously this shouldn't be used in production) 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';
}

Instantiating the SessionManager class will set the session handler to Redis. This comes with a small test that upon successive page reloads will create and increment a counter. You can connect to the redis server and run a flushall command and observe how the counter gets reset.

One mention is to have the php-redis extension enabled.

$ php -m | grep redis 

Should display 'redis'. If not, that can be installed (in Ubuntu) like this:

sudo apt-get install php-redis

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM