Page 1 sur 1

Effacer les sessions en cours

Posté : 21 mars 2006, 12:16
par John32RR4
Bonjour !

voila je voudrais que l'administrateur puisse fermer toutes les sessions en cours ou seuleument certaines. Cela est il possible ?

Merci

Posté : 21 mars 2006, 12:22
par Ryle
Je suppose que cela doit pouvoir se faire en supprimant les fichiers de session en cours (dans le dossier où sont stockées les sessions.. à voir dans le paramétrage de php)

Mais je n'ai jamais essayé.. celà dit à part ça, je ne vois pas trop de solution pour arrêter une session en cours...

Posté : 21 mars 2006, 12:32
par Invité
Oais je pensais faire ça à la bourrin aussi :) mais bon ... si je veux en effacer que quelques unes...

quelqu'un aurait il une autre solution ?

mercki

Posté : 21 mars 2006, 13:06
par Ryle
bah pour ça tu peux faire une jolie interface pour te lister les fichiers et te demander lesquels tu veux virer :) ... par contre pour savoir laquelle correspond à qui...

Eventuellement dans ton code, quand tu ouvres la sessions, tu changes l'emplacement par défaut pour un emplacement spécifique, dans lequel tu créer un dossier à partir du login ou de l'identifiant (que tu vas donc garder en session)
Comme ca chaque utilisateur aura ses sessions regroupées dans un seul dossier indépendant des autres, et il suffira de le vider pour ne dégager que lui... :)

Posté : 22 mars 2006, 11:38
par sadeq
Je vais essayer de t'expliquer comment faire :

Les sessions sont enregistrées par défaut dans un dossier nommé /tmp
Pour le connaitre le chemin réél par programmation on utiliser la fonction "session_save_path()"
exemple :
//Trouver le chemin des sessions
$chemin = session_save_path();
dans ce dossier on trouve des fichiers de session dont le nom commence par "sess_" suivi d'un code aléatoire qui représente le SID de la session
Exemple : sess_b93495e440ea58498e20d7006899e51b

Pour extraire le SID on peut utiliser une fonction d'expressions réguliaires de type "preg_match" avec le masque d'extraction "#_(.*)$#"
Dans ce masque :
- les parenthèses désignent la partie à extraire après le caractère "_"
- le $ veut dire qu'il s'agit d'une partie allant jusqu'à la fin de la chaine traitée

Il faut donc appliquer ce masque d'extraction sur le nom du fichier de session
Exemple:
//Nom du fichier de session
$entrée = "sess_b93495e440ea58498e20d7006899e51b";
//Extraire le SID
preg_match ("#_(.*)$#",$entrée, $partie); 
$sid = $partie[1]; //$partie : est un tableau contenant le résultat de preg_match
Pour lire le contenu du fichier on peut utiliser la fonction "file_get_contents", puis décomposer se contenu en tableau
sachant que dans un fichier session les variables sont enregistrées séparées par un ;
Exemple de contenu:

Code : Tout sélectionner

variable_1|s:8:"Valeur_1";variable_2|s:8:"Valeur_2";
Exemple:
//Trouver le chemin des sessions
$chemin = session_save_path();
//Nom du fichier de session
$entrée = "sess_b93495e440ea58498e20d7006899e51b";
//Lire contenu du fichier de session
$contenu = file_get_contents("$sessions[chemin]/$entrée");
$contenu = explode (";", $contenu); //transformer en tableau (une ligne par variable de session)
if ($contenu) {
  foreach ($contenu as $ligne){
       //Afficher une ligne du contenu 
       echo "<p>$ligne";
  }
} else echo "<p>Fichier vide";
Mais puisqu'on ne connait pas les noms des fichiers de sessions, on doit parcourir le dossier des sessions pour le faire.
Pour ça il faut utiliser les fonctions "opendir" pour ouvrir le dossier et "readdir" pour accèder aux fichiers et sous-dossiers contenus.
Exemple:
//Trouver le chemin des sessions
$chemin = session_save_path();
//Parcourir le chemin
$dossier = opendir($chemin);
while ($entrée = readdir($dossier)){
	//Extraire seulement les fichiers (is_file)
	if (is_file("$chemin/$entrée")){
             echo "<p>Fichier trouvé : $entrée";
         }
}

Algorithme général


pour récupèrer alors la liste des fichier, il suffit donc de :
- récupèrer le chemin des sessions
- explorer ce chemin pour connaitre les noms des fichiers de session
et les enregistrer dans un tableau

Pour présenter la liste des fichiers trouvés (avec les infos les concernant) et permettre leur suppression, on peut dresser un formulaire tableau en proposant un bouton de suppression qui renvoi le nom du fichier à supprimer.

Pour la suppression l'algorithme est simple :
Pour un fichier reçu pour suppression, on doit activer le droit de suppression chmod(400) ou chmod(200) et puis supprimer avec la fonction "unlink"


Le programme php
<?php
//Gérer les actions du formulaire
if ($_GET){
	extract($_GET);
	//Supprimer des fichiers
	if ($supprimer && $fichier){
		echo "<div class='panneau'><h4 class='alert'>Suppression de fichiers</h4><ul>";
		foreach ($fichier as $f){
			//si le fichier existe : obtenir le droit de suppression (chmod) et supprimer (unlink)
			if ($f && @file_exists($f))
			  if (@chmod($f, 400) && @unlink ($f))  echo "<li>Le fichier '$f' est supprimé.";
				else echo "<li><i>Le fichier '$f' ne peut être supprimé!</i>";
			else echo "<li><i>Le fichier '$f' n'existe plus!</i>";
		}//fichier suivant
		echo "</ul></div>";
	}//fin if
}//fin if

//Lister et gérer les sessions ouvertes sur le serveur : le tableau $sessions sera rempli

//Détecter le serveur et le chemin des fichiers de sessions
$sessions["serveur"] = $_SERVER["SERVER_NAME"];
$sessions["chemin"] = session_save_path();

//Parcourir le chemin
$dossier = opendir($sessions["chemin"]);
while ($entrée = readdir($dossier)){
	//Extraire les fichiers
	if (is_file("$sessions[chemin]/$entrée")){
		//Déterminer le SID du fichier de session : généralement compris dans le nom du fichier après un "_"
		preg_match ("#_(.*)$#",$entrée, $nom); 
		$sid = $nom[1]?trim($nom[1]):null;
		if ($sid){
			//Si le SID est trouvé, il s'agit d'un fichier session : l'enregistrer alors
			$sessions["$sid"]["nom_fichier"] = "$sessions[chemin]/$entrée";
			$sessions["$sid"]["date_création"] = date("Y-m-d", filectime("$sessions[chemin]/$entrée"));
			$sessions["$sid"]["temps_création"] = date("h:m:s", filectime("$sessions[chemin]/$entrée"));
//Lire contenu du fichier de session
			$contenu = file_get_contents("$sessions[chemin]/$entrée");
			$contenu = explode (";", $contenu); //transformer en tableau (une ligne par variable de session)
			if ($contenu) {
				foreach ($contenu as $ligne){
					//Extraire les paires(variable, valeur) enregistrées dans le fichier
					//Les variables de session sont enregistrées sous la forme "variable|type:taille:valeur"
					//Ce qui nous intéresse ce sont la variable et sa valeur :
					//il faut éliminer donc le "|", le "type", la "taille" et les ":"
					preg_match ("#^(.*)\|#", $ligne, $champ1); //$champ1 est la partie "nom de la variable de session"
					//si une variable est trouvée, extraire sa valeur
					if ($champ1[1]){
						preg_match ("#:.*:(.*)$#", $ligne, $champ2); //$champ2 est la partie "valeur de la variable"
						//Enregistrer la valeur si existe sinon elle reste nulle
						$sessions["$sid"]["$champ1[1]"] = $champ2[1]?trim($champ2[1]):null;
					}//fin if
				}//fin foreach: ligne suivante du fichier de session en cours
			}//fin if
		}//fin if
	}//fin if
}//fin while: Fichier de session suivant

//Afficher les fichiers sessions trouvés avec menu de gestion
//Un formulaire de gestion
echo "<div class='afficheur'>
		<form>
		<h1>Gestion des sessions</h1>
		<input type=submit name=actualiser value=Actualiser>
		<input type=submit name=supprimer value=Supprimer><hr>";
if ($sessions){
	//Afficher le chemin des sessions
	echo "<p><b>Serveur : </b><i>$sessions[serveur]</i></p>";
	echo "<p><b>Chemin des fichiers de sessions: </b><i>$sessions[chemin]</i></p>";
	//Parcourir tous les fichiers enregistrés
	foreach ($sessions as $sid => $session){
		if ($session && is_array($session)){
			//Afficher la description et le contenu détaillé du fichier en cours
			//Un checkbox permet de sélectionner le fichier
			echo "<h2 class='checkbox'><input type=checkbox name=fichier[] value='$session[nom_fichier]'> SID : $sid</h2><ul>";
			foreach ($session as $variable => $valeur){
				//Afficher donc les variables de session
				echo "<li>$variable = $valeur";
			}//variable suivante
			echo "</ul>";
		}//fin if
		
	}//fin foreach: fichier de session suivant
}//fin if
else echo "<p><i>Aucun fichier n'est trouvé</i></p>";
echo "</form></div>";
//Fin.
?>
<style>
.afficheur {position:absolute; top:0; left:0; width:600; height:100%; font-size:14; padding:5}
.panneau {position:absolute; top:0; left:600; width:200; height:100%; font-size:12; color:red; 
			border-style:solid; border-left-width:1;border-right-width:0;border-top-width:0;border-bottom-width:0;
			padding:5}
.alert {background:maroon; color:lightyellow}
.checkbox {background:silver; color:maroon}
</style>

Posté : 22 mars 2006, 12:16
par Invité
oaich :)

bin super merci je vais tester ça !

Posté : 22 mars 2006, 13:17
par sadeq
Attention j'ai mis à jour mon post précédent mais c'est juste pour la partie lecture des variables de session (j'ai utilisé "file_get_contents" puis un "explode" au lieu de la lecture par la fonction "file") car dans un fichier de session les variables ne sont pas enregistrées ligne par ligne mais dans une même ligne et séparées par un point-virgule.

Posté : 22 mars 2006, 15:31
par Ripat
sadeq=> Les variables d'un fichier de session sont sérialisées. Ton algo plus haut ne marchera que pour des variables scalaires mais pas pour des tableaux qui sont stockés en session comme:

Code : Tout sélectionner

a:3:{i:0;a:2:{s:3:"aaa";i:1;s:3:"bbb";i:2;}i:1;i:2;i:2;i:3;}
Deux solutions selon le cas:
  • Pour la lecture d'un seul fichier de session:
    session_id('b2c2227203b86d40dc58a47d58ce3b48');
    session_start();
    echo '<pre>';
      print_r($_SESSION); 
    echo '</pre>';
  • pour la lecture, en boucle, de plusieurs fichiers de sessions (session_start, ne peut être invoqué qu'une seule fois dans un script) utiliser plutôt:
    $session_file = file_get_contents('/var/lib/php4/sess_b2c2217203b86d40dc58a47d58ce3b48');
    
    $s = preg_split("#(\w+)\|#", $session_file, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
    $iMax = count($s);
    for($i = 0; $i < $iMax; $i = $i+2) {
        $session[$s[$i]] = unserialize($s[$i+1]);
    }
    echo '<pre>';
      print_r($session);
    echo '</pre>';

Posté : 23 mars 2006, 16:10
par sadeq
Oui c'est vrai Ripat et aussi pour les objets sérialisés dans la session.

Mais comme notre ami n'a pas besoin d'afficher le contenu de la session on peut virer la partie lecture et analyse du contenu (lui il veut supprimer la session)

c'est vrai que j'étais parti sur un truc simpliste.