Php5 - poo - classe gerant session

Contenu du snippet

Encore une classe gérant les sessions sur fichiers,
Avec une détection si le navigateur client autorise ou pas les cookies,
Une fonction d'encodage / décodage du contenu de la session, lourde certes, mais jamais trop prudent sur les fichiers
stockés sur serveur distant... et pour info, je suis novice donc je prends toutes les remarques.

En premier, la classe;
En second, un fichier de test

Source / Exemple :


<?php

class Sessio{
    # DECLARATION DES PROPRIETEES
        // public
            public $sessio_stat                 = 0;
        // protegees
        
        // privees
            private $sessio_url                 = '';
            private $sessio_current_time        = 0;
            private $sessio_current_name        = '';
            private $sessio_old_name            = '';
            private $sessio_cookie_lifetime     = 0;
            private $sessio_path                = '';
            private $sessio_domain              = '';
            private $sessio_https               = false;
            private $sessio_httponly            = true;
            private $sessio_id                  = '';
            private $sessio_expire_restart_auto = false;
            private $sessio_code_clef           = '';

    # FONCTION DE DESTRUCTION TOTAL D'UNE SESSION
        final public function sessio_destruct() {
            # INITIALISE LES VARIABLES LOCALES
                $params		= array();
            # VIDE LA VARIABLE DE SESSION
                $_SESSION	= array();
            # SI LE SERVEUR UTILISE BIEN LES COOKIES DE SESSION
                if( ini_get('session.use_cookies') ){
                    # ON RECUPERE LES PARAMETRES SERVEUR
                        $params = session_get_cookie_params();
                    # ON DESACTIVE LE COOKIE DE SESSION CHEZ LE CLIENT ET ON SUPPRIME LA SESSION COTE SERVEUR
                        // SI LES PARAMETRES DOMAIN ET SECURE NE SONT PAS FOURNIT
                            if( empty($params['domain']) && empty($params['secure']) ){
                                setcookie( $this->sessio_current_name, '', time()-3600, $params['path'] );
                                session_destroy();
                                return true;
                            }
                        // SI LE PARAMETRE SECURE N'EST PAS FOURNIT
                            elseif( empty($params['secure']) ){
                                setcookie( $this->sessio_current_name, '', time()-3600, $params['path'], $params['domain'] );
                                session_destroy();
                                return true;
                            }
                        // SI LES PARAMETRES DOMAIN ET SECURE SONT FOURNIT
                            elseif( !empty($params['domain']) && !empty($params['secure']) ){
                                setcookie( $this->sessio_current_name, '', time()-3600, $params['path'], $params['domain'], $params['secure'] );
                                session_destroy();
                                return true;
                            }
                        // ERREUR SUR LE PARAMETRES DOMAIN
                            throw new Exception('Le domaine est manquant.', 99);
                }
            # LE SERVEUR NE GERE PAS LES COOKIES DE SESSION
                throw new Exception('Le serveur ne gère pas le cookie de session.', 99);
        }

    # FONCTION D'ENCODAGE
        final private function sessio_encode( $sessio_string='' ) {
            if( is_string($sessio_string) && !empty($sessio_string) ) {
                $td     = '';
                $iv     = '';
                $temp1  = '';
                $td = mcrypt_module_open('tripledes', '', 'ecb', '');
				$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
				mcrypt_generic_init($td, $this->sessio_code_clef, $iv);
				$temp1 = mcrypt_generic($td, $sessio_string);
				mcrypt_generic_deinit($td);
				mcrypt_module_close($td);
                if( is_string($temp1) && !empty($temp1) ) {
                    return $temp1;
                }
                # ERREUR FATAL: retour d'encodage incorrecte
                    throw new Exception('Retour d\'encodage incorrecte.', 99);
            }
            # ERREUR FATAL: paramètre erroné
                throw new Excpetion('Le paramètre est incorrecte ou vide.', 99);
        }

    # FONCTION DE DECODAGE
        final private function sessio_decode( $sessio_string='' ) {
            if( is_string($sessio_string) && !empty($sessio_string) ) {
                $td     = false;
                $iv     = false;
                $temp1  = false;
                $td = mcrypt_module_open('tripledes', '', 'ecb', '');
				$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
				mcrypt_generic_init($td, $this->sessio_code_clef, $iv);
				$temp1 = mdecrypt_generic($td, $sessio_string);
				mcrypt_generic_deinit($td);
				mcrypt_module_close($td);
                if( is_string($temp1) && !empty($temp1) ) {
                    return $temp1;
                }
                # ERREUR FATAL: retour de decodage incorrecte.
                    throw new Exception('Retour de décodage incorrecte.', 99);
            }
            # ERREUR FATAL: paramètre erroné
                throw new Exception('Le paramètre est incorrecte ou vide.', 99);
        }

    # FONCTION D'INITIALISATION OU DE RESTAURATION D'UNE SESSION
        final private function sessio_start() {
            # CONTROL DU DOMAINE
                if( !is_null($this->sessio_domain) ) {
                    # INITIALISE LA DUREE DE VIE DES SESSIONS SUR LE SERVEUR
                        session_set_cookie_params( $this->sessio_cookie_lifetime, $this->sessio_path, $this->sessio_domain, $this->sessio_https, $this->sessio_httponly );
                    # HEURE OU LA SESSION DEMARRE
                        $this->sessio_current_time = time();
                    # DEMARRE OU RESTAURE UNE SESSION 
                        session_start();
                    # SI LA SESSION N'EXISTE PAS ON REGENERE L'IDENTIFIANT DE SESSION
                        if( empty($_SESSION[$this->sessio_current_name]) ) {
                            session_regenerate_id(true);
                        }
                    # ON RECUPERE LE NOUVEAU IDENTIFIANT
                        $this->sessio_id = session_id();
                    # CONTROLE DE L'IDENTIFIANT
                        if( is_string($this->sessio_id) && !empty($this->sessio_id) && strlen($this->sessio_id)===32 ) {
                            return true;
                        }
                    # ERREUR FATAL DANS TOUS LES AUTRES CAS
                        throw new Exception('L\'identifiant généré est erroné.', 99);
                }
                # ERREUR FATAL: Le nom de domaine est erroné
                    throw new Exception('Nom de domaine incorrecte.', 99);
        }

    # NOUVEAU UTILISATEUR
        final private function sessio_new_user() {
            # EST-CE BIEN UN NOUVEAU UTILISATEUR
                if( empty($_COOKIE[$this->sessio_current_name]) && empty($_SESSION[$this->sessio_current_name]) ) {
                    # OUI
                    # INITIALISATION DES VARIABLES LOCALES
                        $temps_max      = null;
                        $ip             = null;
                        $browser        = null;
                        $session_temp   = null;
                        $session_serial = null;
                        $session_encode = null;
                    # INITIALISATION DES DONNEES UNIQUES
                        $temps_max  = $this->sessio_cookie_lifetime + $this->sessio_current_time;
                        $ip         = md5($_SERVER['REMOTE_ADDR']);
                        $browser    = md5(serialize(get_browser(null,true)));
                    # CONTROL DES DONNEES
                        if( is_int($temps_max) && $temps_max>0 && is_string($ip) && strlen($ip)===32 && is_string($browser) && strlen($browser)===32 ) {
                            # CONSTRUCTION DU CONTENU DE LA SESSION
                                $session_temp = array(  0   =>  array(  'time'      =>  $temps_max,
                                                                         'ip'        =>  $ip,
                                                                         'browser'   =>  $browser
                                                                    ),
                                                        1   =>  array()
                                                    );
                            # ON SERIALISE POUR ENCODAGE
                                $session_serial = serialize($session_temp);
                            # ON ENCODE
                                $session_encode = $this->sessio_encode($session_serial);
                            # ON CREE LA SESSION SI ENCODAGE OK
                                if( is_string($session_encode) && strlen($session_encode)>1 ) {
                                    $_SESSION[$this->sessio_current_name] = array( 0 => $session_encode );
                                    return true;
                                }
                                throw new Exception('Problème d\'encodage.', 99);
                        }
                    # ERREUR FATAL: une des trois varaibles d'unicitées est erronée
                        throw new Exception('Une des trois variables d\'unicitées est erronée.', 99);
                }
            # NON
                return false;
        }

    # UTILISATEUR EXISTANT
        final private function sessio_exist_user() {
            # EST-CE BIEN UN UTILISATEUR EXISTANT
                if( !empty($_COOKIE[$this->sessio_current_name]) && !empty($_SESSION[$this->sessio_current_name]) ) {
                    # OUI
                    # INITIALISATION DES VARIABLES LOCALES
                        $session_decode     = null;
                        $session_unserial   = null;
                        $tempsMax           = null;
                        $IP                 = null;
                        $BROWSER            = null;
                    # DECODAGE DE LA SESSION
                        $session_decode     = $this->sessio_decode($_SESSION[$this->sessio_current_name][0]);
                        if( is_string($session_decode) && !empty($session_decode) ) {
                            # ON DESERIALISE
                            $session_unserial = unserialize($session_decode);
                            if( is_array($session_unserial) && !empty($session_unserial) ) {
                                # CONTROLE DES DONNEES UNIQUES
                                    $tempsMax   = ( isset($session_unserial[0]['time']) ) ? $session_unserial[0]['time'] : null;
                                    $IP         = ( isset($session_unserial[0]['ip']) ) ? $session_unserial[0]['ip'] : null;
                                    $BROWSER    = ( isset($session_unserial[0]['browser']) ) ? $session_unserial[0]['browser'] : null;
                                    if( !is_null($tempsMax) && is_int($tempsMax) && $tempsMax>0 && !is_null($IP) && is_string($IP) && strlen($IP)===32 && !is_null($BROWSER) && is_string($BROWSER) && strlen($BROWSER)===32 ) {
                                        if( $IP===md5($_SERVER['REMOTE_ADDR']) && $BROWSER===md5(serialize(get_browser(null,true))) ) {
                                            # CONTROLE DE LA DUREE DE VALIDITE DE LA SESSION
                                                $tempsMaxClient = (int)round(($this->sessio_cookie_lifetime / 3),0);
                                                if( !( time()>=($tempsMax-$tempsMaxClient) ) ) {
                                                    # SESSION VALIDE
                                                        return true;
                                                }
                                                # SESSION INVALIDE
                                                    $this->sessio_destruct();
                                                    return -1;
                                        }
                                        # ERREUR FATAL: empreinte de l'identité incorrecte
                                            throw new Exception('L\'empreinte de l\'identité de l\'internaute est incorrecte.',99);
                                    }
                                    # ERREUR FATAL: une des trois données d'unicitées retourné est erronée
                                        throw new Exception('Une des trois variables d\'unicitées retournée est erronée.', 99);
                            }
                            # ERREUR FATAL: la session retournée est incorrecte
                                throw new Exception('La session retournée est incorrecte.', 99);
                                exit(0);
                        }
                        # ERREUR FATAL: problème de decodage
                            throw new Exception('Problème de décodage.', 99);
                }
            # NON
                return false;
        }

    # PAR SECURITE, SI JUSTE LE COOKIE EXISTE
        final private function sessio_just_cookie_exist() {
            # COOKIE EXISTE ET SESSION INEXISTANTE
                if( !empty($_COOKIE[$this->sessio_current_name]) && empty($_SESSION[$this->sessio_current_name]) ) {
                    # DESTRUCTION DU COOKIE & ON RECHARGE LE SITE
                        $this->sessio_destruct();
                        header('Location: http://'.$this->sessio_url, true, 200);
                        exit();
                }
            # ERREUR FATAL: Normalement pas possible d'arrivé jusque là !
                throw new Exception('Les trois test sur le cookie et la session non rien donnés.', 99);
        }

    # ECRIRE DES DONNEES DANS LA SESSION
        final public function sessio_write($cle, $valeur) {
            try{
            if( !empty($_SESSION[$this->sessio_current_name]) ) {
                if( is_numeric($cle) || (is_string($cle) && !empty($cle)) ) {
                    $session_decode     = null;
                    $session_unserial   = null;
                    $session_serial     = null;
                    $session_encode     = null;
                    # Si des donnees existes, on decode
                    if( !empty($_SESSION[$this->sessio_current_name][1]) ) {
                        $session_decode     = $this->sessio_decode($_SESSION[$this->sessio_current_name][1]);
                        $session_unserial   = unserialize($session_decode);
                    }
                    $session_unserial[$cle] = $valeur;
                    if( $session_unserial[$cle]===$valeur ) {
                        $session_serial = serialize($session_unserial);
                        $session_encode = $this->sessio_encode($session_serial);
                        if( is_string($session_encode) && !empty($session_encode) ) {
                            $_SESSION[$this->sessio_current_name][1] = $session_encode;
                            return true;
                        }
                        # ERREUR FATAL: encodage incorrecte
                            throw new Exception('L\'encodage est incorrecte.', 99);
                    }
                    # LA PAIRE CLE/VALEUR N'A PAS ETE ECRITE
                    return false;
                }
                # CLE INVALIDE
            }
            # PAS DE SESSION: ON ECRIT RIEN
            return null;
            }catch(Exception $e){
                # ERREUR FATAL
                exit();
            }
        }

    # LIRE UNE DONNEES DANS LA SESSION
        final public function sessio_read($cle) {
            try{
            if( !empty($_SESSION[$this->sessio_current_name]) ) {
                if( is_numeric($cle) || (is_string($cle) && !empty($cle)) ) {
                    $session_decode     = null;
                    $session_unserial   = null;
                    # Si des donnees existes, on decode
                    if( !empty($_SESSION[$this->sessio_current_name][1]) ) {
                        $session_decode     = $this->sessio_decode($_SESSION[$this->sessio_current_name][1]);
                        $session_unserial   = unserialize($session_decode);

                        if( isset($session_unserial[$cle]) ) {
                            return $session_unserial[$cle];
                        }
                        # LA CLEF N'EXISTE PAS
                    }
                    # AUCUNE DONNEES EXISTE
                }
                # CLE INVALIDE
            }
            # PAS DE SESSION: ON ECRIT RIEN
            return null;
            }catch(Exception $e){
                # ERREUR FATAL
                exit();
            }
        }

    # SUPPRIMER UNE DONNEE DANS LA SESSION
        final public function sessio_remove($cle) {
            try{
            if( !empty($_SESSION[$this->sessio_current_name]) ) {
                if( is_numeric($cle) || (is_string($cle) && !empty($cle)) ) {
                    $session_decode     = null;
                    $session_unserial   = null;
                    $session_serial     = null;
                    $session_encode     = null;
                    # Si des donnees existes, on decode
                    if( !empty($_SESSION[$this->sessio_current_name][1]) ) {
                        $session_decode     = $this->sessio_decode($_SESSION[$this->sessio_current_name][1]);
                        $session_unserial   = unserialize($session_decode);
                    }
                    if( isset($session_unserial[$cle]) ) {
                        unset($session_unserial[$cle]);
                        $session_serial = serialize($session_unserial);
                        $session_encode = $this->sessio_encode($session_serial);
                        if( is_string($session_encode) && !empty($session_encode) ) {
                            $_SESSION[$this->sessio_current_name][1] = $session_encode;
                            return true;
                        }
                        # ERREUR FATAL: encodage incorrecte
                            throw new Exception('L\'encodage est incorrecte.', 99);
                    }
                    # LA CLE N'EXISTE PAS
                    return false;
                }
                # CLE INVALIDE
            }
            # PAS DE SESSION: ON ECRIT RIEN
            return null;
            }catch(Exception $e){
                # ERREUR FATAL
                exit();
            }
        }

    # CONSTRUCTEUR
        final public function __construct( $session_url, $session_name='PHPSESSID', $session_cookie_lifetime=120,
                                           $session_path='/', $session_domain='', $session_https=false, $session_httponly=true, $session_expire_restart_auto=false,
                                           $session_code_clef='' ) {

            # VARIABLES LOCALES
                $cookie_accept = null;

            # ASSIGNATION DES PROPRIETEES
                $this->sessio_current_name      = ( is_string($session_name) && !empty($session_name) ) ? $session_name : 'PHPSESSID';
                $this->sessio_old_name          = session_name( $this->sessio_current_name );
                $this->sessio_cookie_lifetime   = ( is_int($session_cookie_lifetime) && $session_cookie_lifetime>=10 ) ? $session_cookie_lifetime : 10;
                $this->sessio_path              = ( is_string($session_path) && !empty($session_path) && strlen($session_path)>=3 ) ? $session_path : '/';
                $this->sessio_domain            = ( is_string($session_domain) && !empty($session_domain) && strlen($session_domain)>=5 ) ? $session_domain : null;
                $this->sessio_https             = ( is_bool($session_https) ) ? $session_https : false;
                $this->sessio_httponly          = ( is_bool($session_httponly) ) ? $session_httponly : true;
                $this->sessio_url               = ( is_string($session_url) && !empty($session_url) ) ? $session_url : null;
                $this->sessio_expire_restart_auto= ( is_bool($session_expire_restart_auto) ) ? $session_expire_restart_auto : false;
                $this->sessio_code_clef         = ( is_string($session_code_clef) && strlen($session_code_clef)===24 ) ? $session_code_clef : 'AbZyuioQATR1239g7S7E6W3i';
                
            # TRY ERROR
                try{
                    # LANCE UNE SESSION
                        $this->sessio_start();
                    # NOUVEAU UTILISATEUR ou UTILISATEUR EXISTANT
                        $new_user = $this->sessio_new_user();
                        if( $new_user===false ) {
                            $exist_user = $this->sessio_exist_user();
                            if( $exist_user===false ) {
                                $this->sessio_just_cookie_exist();
                            }
                            elseif( $exist_user===-1 ) {
                                # TIMEOUT
                                if( $this->sessio_expire_restart_auto==true ) {
                                    header('Location: http://'.$this->sessio_url, true, 200);
                                    exit(0);
                                }
                                $this->sessio_stat = -1;
                            }
                            elseif( $exist_user===true ) {
                                $this->sessio_stat = true;
                            }
                        }
                        elseif( $new_user===true ) {
                            $this->sessio_stat = 1;
                        }
                    # THE END MAIN SESSION
                    # ********************************************************
                    # **** AND NOW: NAVIGATOR, COOKIE OR NOT COOKIE ? :-) ****
                    # ********************************************************
                    
                        # Test si accepte les cookies
                        $cookie_accept = $this->sessio_read('cookie_accept');
                        if( $cookie_accept!==true && $this->sessio_stat!==-1 ) {

                            # 1er APPEL DU SITE PAR LE CLIENT
                            if( empty($_REQUEST['PSG2']) && is_null($cookie_accept) ) {
                                # ON ECRIT DANS LA SESSION
                                    if( $this->sessio_write('cookie_accept', false)===true ) {
                                        # ON DECLENCHE UN SECOND APPEL DE L'URL
                                        header('Location: http://'.$this->sessio_url.'?PSG2=yes', true, 200);
                                        exit(0);
                                    }
                                # ERREUR FATAL: IMPOSSIBLE D'ECRIRE DANS LA SESSION
                                    throw new Exception('Problème d\'écriture dans la variable de session.', 99);
                            }
                            # ANALYSE DU SECOND APPEL GENERE AUTOMATIQUEMENT
                            elseif( !empty($_REQUEST['PSG2']) && is_null($cookie_accept) ) {
                                # LES COOKIES NE SONT PAS ACCEPTES PAR LE NAVIGATEUR DU CLIENT
                                # SI UN COOKIE EXISTE, LE SUPPRIMER
                                (!empty($_SESSION[$this->sessio_current_name])) ? $this->sessio_destruct() : null;
                                $this->sessio_stat = 0;
                            }
                            elseif( !empty($_REQUEST['PSG2']) && $cookie_accept===false ) {
                                # LES COOKIES SONT ACCEPTES PAR LE NAVIGATEUR DU CLIENT
                                    # ON ECRIT DE NOUVEAU SUR LA VARIABLE DE SESSION
                                    if( $this->sessio_write('cookie_accept',true)!==true ) {
                                        throw new Exception('Problème d\'écriture dans la variable de session.', 99);
                                    }
                                # SI COOKIE ET PARAMETRE URL EXISTENT, ON REMET EN PLACE UNE URL SANS PARAMETRE
                                header('Location: http://'.$this->sessio_url, true, 200);
                                exit(0);
                            }
                        }
                        # SI COOKIE EXISTE ET LE PARAMETRE URL EXISTE, ON REMET EN PLACE UNE URL SANS PARAMETRE
                        elseif( $cookie_accept===true && !empty($_REQUEST['PSG2']) ) {
                            header('Location: http://'.$this->sessio_url, true, 200);
                            exit(0);
                        }

                    # *****************
                    # **** THE END ****
                    # *****************  
                } catch (Exception $e) {
                        $err = array(   'code'      => $e->getCode(),
                                        'msg'   => $e->getMessage(),
                                        'file'      => $e->getFile(),
                                        'line'      => $e->getLine(),
                                        'trace'     => $e->getTrace(),
                                        //'previous'  => $e->getPrevious()
                                    );
                        if( isset($err['code']) && is_int($err['code']) ) {
                            switch($err['code']) {
                                # ICI TRAITEMENT DES ERREURS GENEREES, A VOUS DE VOIR...
                                case 99:
                                    # ERREUR FATAL
                                        echo '<pre>'."\n";
                                        print_r($err);
                                        echo '<br />';
                                        var_dump($_COOKIE);
                                        echo '<br />';
                                        var_dump($_SESSION);
                                        echo '</pre>'."\n";
                                        break;
                            }
                            exit();
                        }
                        exit();
                }
        }
}

?>

## TESTE ##

<?php

/**

  • @author
  • @copyright 2012
  • /
require_once( 'ma_classe.dans_mon_include.php5' ); # variable pour la classe $domaine = '.mondomaine.ext'; $base_url = 'www.monsite.fr'; $path = '/'; $nom_de_session = 'ma_session'; $duree_de_vie_cookie = 60; // en seconde $session_https = false; $session_httponly = true; $session_restart_auto = false; # créer une session $session = new Sessio($base_url, $nom_de_session, $duree_de_vie_cookie, $path, $domaine, $session_https, $session_httponly, $session_restart_auto, ''); echo '<br /><h1>SESSION STAT</h1><pre>'; $stat_ses = array( '0' => 'COOKIE NOT ACCEPTED', '-1' => 'TIMEOUT', '1' => 'SESSION OK' ); $ret_stat = (string)$session->sessio_stat; var_dump($stat_ses[$ret_stat]); echo '</pre><br /><br />'; echo '<br /><h1>SESSION</h1><pre>'; var_dump($_SESSION[$nom_de_session]); echo '</pre><br /><br />'; echo '<br /><h1>TEST: LECTURE D\'UNE CLEF INEXISTANTE: "12"</h1><pre>'; var_dump($session->sessio_read('12')); echo '</pre><br /><br />'; echo '<br /><h1>SESSION</h1><pre>'; var_dump($_SESSION[$nom_de_session]); echo '</pre><br /><br />'; echo '<br /><h1>TEST: ECRITURE ( CLE = "13" )</h1><pre>'; var_dump($session->sessio_write('13',array('1' => 'un', '2' => 'deux'))); echo '</pre><br /><br />'; echo '<br /><h1>SESSION</h1><pre>'; var_dump($_SESSION[$nom_de_session]); echo '</pre><br /><br />'; echo '<br /><h1>TEST: LECTURE ( CLE = "13" )</h1><pre>'; var_dump($session->sessio_read('13')); echo '</pre><br /><br />'; echo '<br /><h1>TEST: LECTURE DE "COOKIE_ACCEPT"</h1><pre>'; var_dump($session->sessio_read('cookie_accept')); echo '</pre><br /><br />'; echo '<br /><h1>SESSION</h1><pre>'; var_dump($_SESSION[$nom_de_session]); echo '</pre><br /><br />'; echo '<br /><h1>TEST: SUPPRIME LA CLEF "13" </h1><pre>'; var_dump($session->sessio_remove('13')); echo '</pre><br /><br />'; echo '<br /><h1>TEST: LECTURE DE LA CLEF "13"</h1><pre>'; var_dump($session->sessio_read('13')); echo '</pre><br /><br />'; echo '<br /><h1>SESSION</h1><pre>'; var_dump($_SESSION[$nom_de_session]); echo '</pre><br /><br />'; ?>

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.