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 />';
?>
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.