PHP session perso : session_start() en erreur.

WRInaute accro
Bonjour

Après tests de ma gestion perso ( avec Redis ) de sessions en PHP sur mon ordi en local, la fonction session_start() ne marche pas.

Message d'erreur "PHP message: PHP Warning: session_start(): Failed to read session data: user (path: /var/lib/php/session) in /var/www/html/php/config/sessions_handler.php on line 292

Sur le php.ini, le session_handler est à user.

Je ne sais pas où çà bugue.

Le session.serialize est à php_serialize.

Merci beaucoup de votre aide.


PHP:
<?php
require(__DIR__ . '/clientID.php');
define('MAXLIFETIME', ini_get('session.gc_maxlifetime'));
define('MAX_IDLE_TIME', 100);
class CustomSessionHandler implements SessionHandlerInterface,
        SessionIdInterface,
        SessionUpdateTimestampHandlerInterface
{
        protected $redisConn;
        protected $lastCreatedId;
        protected $isChanged;
        /**
        * 1ère fonction.
        **/
        public function open($savePath, $sessionName)
        {
                //                ob_start();
                $this->isChanged = false;
                /**
                Parameters
                    host: string. can be a host, or the path to a unix domain socket. Starting from version 5.0.0 it is possible to specify schema port: int, optional
                    timeout: float, value in seconds (optional, default is 0 meaning unlimited)
                    reserved: should be NULL if retry_interval is specified
                    retry_interval: int, value in milliseconds (optional)
                    read_timeout: float, value in seconds (optional, default is 0 meaning unlimited)
                **/
                try
                {
                        $this->redisConn = new Redis();
                } catch(Exception $e) {
                        echo "Erreur instanciation classe Redis : " . $e->getMessage();
                        return false;
                }   
                try
                {
                        $this->redisConn->connect('/var/run/redis/redis.sock'); // unix domain socket.
                        return true;
                } catch(Exception $e) {
                        echo "Erreur connexion serveur Redis : " . $e->getMessage();
                        return false;
                }
                /* With PhpRedis >= 5.3.0 you can specify authentication information on connect */
                /**
                if($this->redisConn->connect('/var/run/redis/redis.sock', 1, NULL, 100, 0, ['auth' => ['phpredis', 'phpredis']]) === true)
                {
                    return true;
                }
                **/
                return false;
                // return value should be true for success or false for failure
        }
        /**
        * 2ème fonction.
        * ( si nouvelle session ).
        **/
        public function create_sid()
        {
                try
                {
                        $this->lastCreatedId = clientID();
                } catch(Exception $e) {
                    echo "Erreur création Id : " . $e->getMessage();
                    return false;
                }
                // invoked internally when a new session id is needed
                // no parameter is needed and return value should be the new session id created
                return $this->lastCreatedId;
        }
        public function validateId($sessionId)
        {
                if ($sessionId === $this->lastCreatedId) {
                        echo "\t\tSession Id OK = "  . $this->lastCreatedId . "<br />\n";
                        return true;
                }
                // return value should be true if the session id is valid otherwise false
                // if false is returned a new session id will be generated by php internally
                // checks session existance
        }
        /**
        * Dernière fonction.
        **/
        public function close()
        {
                $this->gc(MAXLIFETIME);
                echo "\t\tSession closed.<br />\n";
                //                ob_flush();
                return $this->redisConn->close();
                // return value should be true for success or false for failure
        }
        /**
        * 3ème fonction
        * si nouvelle fonction,
        * ou 2ème fonction.
        **/
        public function read($id)
        {
                $array_read = array();
                $array_read = $this->redisConn->hGetAll($id);
                echo "\t\tSession Read.<br />\n";
                print_r($array_read);
                echo "<br />\n";
                return $array_read;
                //                return (string)@file_get_contents("$this->savePath/sess_$id");
                // return value should be the session data or an empty string
        }
        /**
        * Avant-dernière fonction,
        * ( si session_write_close(); )
        **/
        public function write($id, $data)
        {
                $array_write = array();
                $array_write = json_decode(json_encode(unserialize($data)), true);
                echo "\t\tSession Write.<br />\n";
                print_r($array_write);
                echo "<br />\n";
                $this->redisConn->hMSet($id, $array_write);
                return true;
                //                return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
                // return value should be true for success or false for failure
        }
        /**
        * Avant-dernière fonction,
        *         après 
        *    session_regenerate_id(),
        *    session_destroy(),
        *    ou session_decode() === false
        **/
        public function destroy($id)
        {
                echo "\t\tSession Destroyed.<br />\n";
                /**
                * Seulement
                * pour la session
                *     $id.
                **/
                $array_del = array();
                $array_del = $this->redisConn->hGetAll($id);
                foreach($array_del as $key)
                {
                        $this->redisConn->del($key);
                }
                //                $this->redisConn->del($id);
                return true;
                // return value should be true for success or false for failure
        }
        /**
        * Après session_start(),
        * en fonction de 
        * session.gc_divisor, 
        * session.gc_probability, 
        * session.gc_maxlifetime
        **/
        /**
        * Fonction globale
        **/
        public function gc($maxlifetime)
        {
                $array_del = array();
                $array_del = $this->redisConn->keys('*');
                echo "\t\tSession Gc.<br />\n";
                print_r($array_del);
                echo "<br />\n";
                foreach($array_del as $key)
                {
                        if(($this->redisConn->ttl($key) + $maxlifetime) < $maxlifetime)
                        {
                                $this->redisConn->del($key);
                        }
                }
                return true;
                // return value should be true for success or false for failure
                /**
                foreach (glob("$this->savePath/sess_*") as $file) {
                        if (filemtime($file) + $maxlifetime < time() && file_exists($file)) {
                                unlink($file);
                        }
                }
                **/
        }
        public function updateTimestamp($id, $data)
        {
                $array_data = array();
                $array_data = json_decode(json_encode(unserialize($data)), true);
                echo "\t\tSession Updated.<br />\n";
                foreach($array_data as $key)
                {
                        if(!$this->redisConn->exists($key))
                        {
                                return $this->redisConn->setTimeout($key, MAXLIFETIME);
                        }
                        else
                        {
                                return $this->redisConn->setTimeout($key, $this->redisConn->ttl($key) + MAX_IDLE_TIME);
                        }
                }
                return false;
                // return value should be true for success or false for failure
        }
}
$handler = new CustomSessionHandler();
session_set_save_handler(
        array($handler, 'open'),
        array($handler, 'close'),
        array($handler, 'read'),
        array($handler, 'write'),
        array($handler, 'destroy'),
        array($handler, 'gc'),
        array($handler, 'create_sid'), 
        array($handler, 'validateId'), 
        array($handler, 'updateTimestamp'));
//    session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid [, callable $validate_sid [, callable $update_timestamp ]]] ) : bool
register_shutdown_function('session_write_close');
session_start();
?>
 
WRInaute accro
Excusez-moi

Pour la configuration de /etc/php.ini , /etc/redis.conf , et /etc/php-fpm.d/www.conf , pour gérer les sessions en PHP avec Redis :

Je suis en PHP 7.4 sur mon ordinateur, où je fais tous les tests.

Il semblerait ( d'après le net ) qu'il y ait un bug spécifique à PHP versions 7.2 et 7.4 pour les sessions mode user.

Ce mode déclenche le message d'erreur "Unable to run mod user ( path: ... )".

J'ai tout essayé pour configurer ces trois fichiers.

Je lance le serveur Redis :

Code:
   # /etc/redis.conf
  unixsocket /var/run/redis/redis.sock?persistent=1&weight=1&database=0
  unixsocketperm 777


Dans /etc/php.ini :

Code:
session.save_handler = user
session.save_path = "unix:///var/run/redis/redis.sock?persistent=1&weight=1&database=0"

Dans /etc/php-fpm.d/www.sock :

Code:
php_value[session.save_handler] = user
php_value[session.save_path]    = "unix:///var/run/redis/redis.sock?persistent=1&weight=1&database=0"

Cà ne marche pas.

Voici le log de mon sessions_handler.php, lancé sous root :

Code:
Running session_set_save_handler();
Preparing session_write_close();
Instanciation class Redis done.
Connect to Redis server done.
Session Id created: 7b51cbaa-0296-4c34-9388-2a0e00039dfd
        Data read : 
        Data write : 
        Updating session data while closing the session.

Merci beaucoup.
 
WRInaute accro
Hé bé

Cà semble fonctionner :

Code:
root@ortolo config]# cat  redis.log

Running session_set_save_handler();
Preparing session_write_close();
Instanciation class Redis done.
Connect to Redis server done.
        Data read : 
        Data write : 
        Data TTL updated : 
        Succedded while updating Data TTL : 
        Updating session data while closing the session.

Je vais voir demain si les variables $_SESSION sont alimentées.

Plouf.

Bien à vous.
 
WRInaute accro
Je ne résiste pas :


Code:
Running session_set_save_handler();
Preparing session_write_close();
Instanciation class Redis done.
Connect to Redis server done.
        Data read : MODE => 1
        Data read : REDIRECT => 1
        Data read : TEND => 3
        Data read : AFFIC => 0
        Data read serialized : a:4:{s:4:"MODE";s:1:"1";s:8:"REDIRECT";s:1:"1";s:4:"TEND";s:1:"3";s:5:"AFFIC";s:1:"0";}
        Data writing : a:4:{s:4:"MODE";i:1;s:8:"REDIRECT";i:1;s:4:"TEND";i:3;s:5:"AFFIC";s:1:"0";}
        Data write : MODE => 1
        Data write : REDIRECT => 1
        Data write : TEND => 3
        Data write : AFFIC => 0
        MODE : 1
        REDIRECT : 1
        TEND : 3
        AFFIC : 0
        Data written : MODE => 1
        Data written : REDIRECT => 1
        Data written : TEND => 3
        Data written : AFFIC => 0
        Data TTL updated : 0 => 271e72b2-4092-4e20-a7db-a87a6a4ee8f1
        Succeded while updating Data TTL : 0 => 271e72b2-4092-4e20-a7db-a87a6a4ee8f1
        Updating session data while closing the session.

Cà boume.
 
WRInaute accro
Bonjour

A propos de la méthode "keys()"de Redis en PHP :

Quels formats pour la regex entre parenthèses ?

Est-ce que "[a-z0-9-]" est possible ?


Code:
        $array_del = $this->redisConn->keys("*");

J'ai vu sur le net que HScan était plus économe côté charge serveur Redis, que keys().

Quelle est la syntaxe de HScan en PHP ?

Merci beaucoup.
 
Discussions similaires
Haut