Problème de session en php

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Problème de session en php

Re: Problème de session en php

par AB » 07 oct. 2009, 18:34

Trouvé !!!

Lorsqu'on tente de faire une mise à jours trop rapidement, les deux requêtes sont identique :
UPDATE users_sessions SET last_visit = "2009-10-08 13:24:48", page='256' WHERE sid='1p09b1bei6kjcac8da5f26hre2'
Etant donné que ces informations sont déjà présente dans la base de donnée, il n'y a aucun enregistrement affecté..

C'était donc tout con..

Maintenant, existe t'il une solution ? (Autre que faire un SELECT COUNT(*) si le résultat vaut à ? )


Edit :

Une variable de session avec time() je compare si c'est dans la même seconde que la dernière vérification, je ne vérifie pas.
Oui il me semble que tu as trouvé la solution la plus efficace pour résoudre ton pb :)

Effectivement ton pb rappel à ceux qui liront ce topic qu'un update s'effectue uniquement si les nouvelles données sont différentes de celles déjà enregistrées :wink:

Re: Problème de session en php

par Number » 07 oct. 2009, 14:01

Trouvé !!!

Lorsqu'on tente de faire une mise à jours trop rapidement, les deux requêtes sont identique :
UPDATE users_sessions SET last_visit = "2009-10-08 13:24:48", page='256' WHERE sid='1p09b1bei6kjcac8da5f26hre2'
Etant donné que ces informations sont déjà présente dans la base de donnée, il n'y a aucun enregistrement affecté..

C'était donc tout con..

Maintenant, existe t'il une solution ? (Autre que faire un SELECT COUNT(*) si le résultat vaut à ? )


Edit :

Une variable de session avec time() je compare si c'est dans la même seconde que la dernière vérification, je ne vérifie pas.

Re: Problème de session en php

par Number » 07 oct. 2009, 13:47

Petite info supplémentaire :

Pour la vérification de la connexion j'utilise une class :
class Session {

	private $sid;
	private $user_id;
	private $conn;
	private $isvalid = false;
	private $ip;
	
	public function __construct() {

		global $config;
		
		session_start();
		$this->getInfo();
		
		//sleep(1);
		
		$this->conn 	= Database::getInstance($config['db_name']);
		$this->ip 	= $_SERVER['REMOTE_ADDR'];
	}

	private function getInfo() {
	
		if(!empty($_SESSION['user_id'])) {
			$this->sid 		= $_SESSION['PHPSESSID'];
			$this->user_id 	= $_SESSION['user_id'];
		} elseif(!empty($_COOKIE['user_id'])) {
			$this->sid 		= $_COOKIE['sid'];
			$this->user_id 	= $_COOKIE['user_id'];
		}
	}

	public function userConnected() {
	
		if($this->isvalid  == true || $this->validSession()) {
			return $this->user_id;
		} else {
			return 0;
		}
	}

	private function validSession() {

		
		if($this->isvalid == true) {
		
			return true;
			exit;
		}
	
		//Vérifie que l'on à bien un sid
		if(!is_null($this->sid)) {
			$page = $this->getPage();
			$valid = $this->conn->exec("UPDATE users_sessions SET last_visit = NOW(), page='".$_SESSION['compteur']."' WHERE sid='".$this->sid."'");
			
			if($valid >= 1) {
				echo "Update de $valid enregistrement(s) sur un total de ";
				echo $valid."</br>";
				$this->isvalid = true;
				return true;
			} else {
				$query = $this->conn->query("SELECT count(*) as result FROM users_sessions WHERE sid='".$this->sid."'");
				$row = $query->fetch();
				echo '<p style="color: red;">Update de '.$valid.' enregistrement(s) sur un total de ';
				echo $row['result']."</p>";
			}
		}
		
		return false;
	}
  • J'instancie la class, il me crée une session et vérifie via le getinfo si il existe un cookie ou une variable de session.
  • Dans ma page index.php lors de la connexion, je crée une session (Ajout d'un enregistrement dans la db, création d'un cookie ou d'une session)
  • Ensuite sur les pages suivante, je vérifie à l'aide de la méthode : userConnected si l'utilisateur est connecté ou pas
  • La méthode userConnected fait appel à la méthode verifSession qui comme vous vous en doutez vérifie la présence de la session dans la db.
J'ai commenté dans mon constructeur la ligne "sleep" parce qu'après certain test, je me suis rendu compte qu'avez le sleep, çe semblait fonctionner (Plus de déco si je rafraichis trop vite). Je suppose que çe comportement est du au faite que le script n'a pas le temps de se terminer vu que je réactualise plus vite.

Mais la ou ça devient étrange, c'est que si je met ce code :
		if(empty($_SESSION['compteur'])) {
			$_SESSION['compteur'] = 0;
		} else {
			$_SESSION['compteur'] = $_SESSION['compteur'] + 1;
		}
à la place du sleep, alors il ne semble plus y avoir de problème...

On dirais, que lors d'une ré actualisation trop rapide, l'update ne peut se faire (comme si il y avait un lock.. )

Auriez-vous une idée ?

Re: Problème de session en php

par Number » 07 oct. 2009, 08:20

Habituellement on utilise une variable de session pour savoir si un utilisateur est connecté... et s'il ne l'est plus la variable de session n'existe plus.
  • L'utilisateur se connecte
  • On crée un cookie ou une session avec le sid crée automatiquement par php
  • J'enregistre ce sid dans la base de donnée qui me sert maintenant d'identifiant pour l'utilisateur
  • Une fois que l'utilisateur se rend sur le site, je trouve un sid (en cookie ou session)
  • Je vérifie que cette session est toujours valable et je met à jour l'enregistrement dans ma table session qui contient : "sid,ip,page courante,last visit"
Ce système est le même que celui utilisé par phpbb par exemple.
La table session me permettant de déconnecter un utilisateur, ou de savoir ou il navigue actuellement ou quand il est venu pour la dernière fois.

Maintenant voiçi ce qui se passe concrètement :
  • L'utilisateur se connecte, je crée un cookie
  • J'actualise la page
  • Le cookie est bien trouvé, je met à jour la table session avec la date de dernière visite et la page courante
  • J'actualise deux fois très rapidement
  • L'enregistrement dans la base de donnée existe bien, mais l'update ne fonctionne pas
  • Je réactualisé en laissant le temps à la page de s'afficher complètement
  • L'update dans la table session fonctionne (Or que je n'ai rien changé à cette enregistrement depuis le début)
Je ne comprend vraiment pas.

Ce n'est pas du au serveur (Tester sur un serveur prod)
Ce n'est pas du à la version de php et/ou mysql (différente sur les 3 serveurs)
Ce n'est apparemment pas du au navigateur (entête envoyée et reçue sont les même)


Edit

Re: Problème de session en php

par AB » 06 oct. 2009, 20:45

Je comprend pas ton système.
Habituellement on utilise une variable de session pour savoir si un utilisateur est connecté... et s'il ne l'est plus la variable de session n'existe plus.

Problème de session en php

par Number » 06 oct. 2009, 17:02

Bonjour à tous,

Voilà je me heurte à un petit soucis.

Dans le but d'économiser les requêtes sur mon site j'utilise une petite astuce pour vérifier qu'un utilisateur est connecté :

Je tente de mettre à jour la session de l'utilisateur connecté (celui, renseigné par son cookie)
Si l'update fonctionne, c'est qu'il y avait bien un enregistrement valide dans la table session -> L'utilisateur est connecté

Si pas évidement, comme vous vous en doutez il est déco..

La ou j'ai un soucis c'est que quand je réactualise trop vite la page, il arrive un truc super étrange :

L'update foire pourtant l'enregistrement existe bien dans la base de donnée..

Voici le code :
		//Vérifie que l'on à bien un sid
		if(!is_null($this->sid)) {
			$page = $this->getPage();
			$valid = $this->conn->exec("UPDATE users_sessions SET last_visit = NOW(), page='".$page."' WHERE sid='".$this->sid."'");
			

			if($valid >= 1) {
				$this->isvalid = true;
				return true;
			} else {
				echo $valid;
				$query = $this->conn->query("SELECT count(*) as result FROM users_sessions WHERE sid='".$this->sid."'");
				$row = $query->fetch();
				
				echo "Il existe ".$row['result']." enregistrement pourtant";
			}
		}
Et je me retrouve sur ma page avec :

0 enregistrements mis à jours
Il existe 1 enregistrement pourtant

Si après ce "bug" je réactualise la page en laissant une seconde avant le refresh, je me retrouve bien connecté..

Le soucis semble venir du faite que j'actualise trop vite (sans laisser le temps au site de s'afficher)

Pour la db j'utilise le PDO..
Le SID est récupéré via un cookie

J'ai ce problème sous ie/chrome/opera/firefox.. (Le soucis ne vient donc pas du cookie... je pense)

Auriez-vous une idée ?

Merci à vous