Bonjour à tous,

Je vous préviens ça me semble un peu compliqué! Voilà deux jours que je cherche partout et je n'ai pas trouvé de cas semblables.

Je fais des tests sur PHP mysqli.
Je souhaite sauver les informations de session dans la base.
J'utilise le fonction session_set_save_handler qui a unefonction callback write. Cette fonction write reçoit les données de session au format text.
Sur mon serveur local (mysql 5.6.17,PHP 5.5.12,APACHE 2.4.9,phpmyadmin 4.1.14) les données sont bien au format text dans phpmyadmin, mais sur le serveur de production les données sont comme si c'était crypté.
J'ai demandé au serveur de prod s'ils avaient une configuration spéciale de PHP, ils m'ont répondu qu'ils avaient installé la configuration par défaut de PHP 5.3.
Je leur ai demandé alors de réinstaller php, mais ils ne peuvent pas car c'est un serveur mutualisé.
J'ai aussi testé tous les formats possibles utf8 ou autre latin.
J'ai aussi changé le moteur de la table, mais sans que cela ne change rien.

J'ai mis quelques echo :

Voilà ce que je vois en local :

*************************************************************
dans construct
dans open
dans read avant query
dans read apres query name|s:9:"127.0.0.1";
avant
Le nom avant 127.0.0.1
Le remote avant 127.0.0.1
Le nom = 127.0.0.1
dans write debut name|s:9:"127.0.0.1";
dans write avant query 1 name|s:9:\"127.0.0.1\";
Session existe
dans write avant query 2 name|s:9:\"127.0.0.1\";
**************************************************************
Comme vous pouvez le remarquer, je dois avoir l'IP du client comme nom dans ma variable de session "name".


Et voilà ce que je vois en prod :

**********************************************************
dans construct
dans open
dans read avant query
dans read apres query h5hzlWbrSrpu0FbLsswyPxvtfb5x7yZbySbo7TvjZHUj2wfZWlw9Mq_qFuYYCCbm
avant
Le nom avant 112.134.167.82
Le remote avant 175.157.228.96
Le nom = 112.134.167.82
dans write debut 5GpJsPV4vvkZdsO52m-p1Fb1rusZHBnCei_6W5OI4J98zYt28ZGUFuEWPu0wsyBI
dans write avant query 1 5GpJsPV4vvkZdsO52m-p1Fb1rusZHBnCei_6W5OI4J98zYt28ZGUFuEWPu0wsyBI
Session existe
dans write avant query 2 5GpJsPV4vvkZdsO52m-p1Fb1rusZHBnCei_6W5OI4J98zYt28ZGUFuEWPu0wsyBI
************************************************************************************

Vous pouvez tester la prod vous même sur ladcan.com/huskk/.

J'ai fait des testes direct sur le serveur de prod avec phpmyadmin et après les requêtes sql les données de sessions sont clairement en texte au bon format.

Donc à mon avis c'est quelque part entre PHP et sql qu'il se passe quelque chose d'étrange.
Je sais que la callback write est appelée elle même par une fonction session_write_close
c'est elle qui donne ce format aux données de session.
Dans le fonction callback read le format est normal.

Je dois reconnaitre que vous m'enlèveriez une drôle d'épine si quelqu'un à déjà rencontré ce phénomène. Et l'a résolu...

Merci pour votre attention.

Voici mon code il a sans doute des problèmes, mais pas au point de faire ce que je décris plus haut :

<?php ob_start();
	$sql_host='localhost';
	$sql_user='ladcan_root';
	$sql_password='************';
	$sql_db='ladcan_test';

	ini_set('session.save_handler','user');

	$session=new Session($sql_host,$sql_user,$sql_password,$sql_db);

	session_set_save_handler(array($session,'open'),
							 array($session,'close'),
							 array($session,'read'),
							 array($session,'write'),
							 array($session,'destroy'),
							 array($session,'gc'));

	session_start();//on démarre la session

	echo('avant');
	echo('<br>');
	$datajs = array();//pour le retour json
	$name = (isset($_SESSION["name"]))? $_SESSION["name"] :'';//La session
	echo('Le nom avant ');
	echo($name);
	echo('<br>');
	echo('Le remote avant ');
	echo($_SERVER["REMOTE_ADDR"]);
	echo('<br>');
	if ($name == ''){$_SESSION["name"] = $_SERVER["REMOTE_ADDR"];}
	echo('Le nom = ');
	echo($_SESSION["name"]);
	echo('<br>');

class Session
{
	public $session_time = 604800;//1 semaine
	public $session = array();
	private $db;
	
	public function __construct($sql_host, $sql_user, $sql_password, $sql_db)
	{
		echo('dans construct');
		echo('<br>');
		$this->host = $sql_host;
		$this->user = $sql_user;
		$this->password = $sql_password;
		$this->dba = $sql_db;
	}
	
	public function open ()//pour l'ouverture
	{
		echo('dans open');
		echo('<br>');
		$this->connect = mysqli_connect($this->host, $this->user, $this->password);//on se connecte a la bdd
		$bdd = mysqli_select_db($this->connect,$this->dba);//on sélectionne la base de données
		
		$this->gc();//on appelle la fonction gc		
		return $bdd;//true ou false selon la réussite ou non de la connexion à la bdd
	}
	
	public function read ($sid)//lecture
	{
        $sid = mysqli_real_escape_string($this->connect,$sid);
		$sql = "SELECT sess_datas FROM session
				WHERE sess_id = '$sid' ";
		
		echo('dans read avant query');
		echo('<br>');
		$query = mysqli_query($this->connect,$sql) or exit(mysqli_error($this->connect));	
		$data = mysqli_fetch_array($query);
		
		echo('dans read apres query ');
		echo($data['sess_datas']);
		echo('<br>');
		if(empty($data)) return FALSE;
		else return $data['sess_datas'];//on retourne la valeur de sess_datas
	}
	
	public function write ($sid, $data)//écriture
	{
		echo('dans write debut ');
		echo($data);
		echo('<br>');
		$expire = intval(time() + $this->session_time);//calcul de l'expiration de la session
		$data = mysqli_real_escape_string($this->connect,$data);//si on veut stocker du code sql
		
		$sql = "SELECT COUNT(sess_id) AS total
			    FROM session
			    WHERE sess_id = '$sid' ";
		
		echo('dans write avant query 1 ');
		echo($data);
		echo('<br>');
		$query = mysqli_query($this->connect,$sql) or exit(mysqli_error($this->connect));
		$return = mysqli_fetch_array($query);
		if($return['total'] == 0)//si la session n'existe pas encore
		{
		echo('Session existe pas ');
		echo('<br>');
			$sql = "INSERT INTO session
				    VALUES('$sid','$data','$expire')";//alors on la crée
			
		}
		else//sinon
		{
		echo('Session existe ');
		echo('<br>');
			$sql = "UPDATE session 
				    SET sess_datas = '$data',
				    sess_expire = '$expire'
				    WHERE sess_id = '$sid' ";//on la modifie
		}		
		echo('dans write avant query 2 ');
		echo($data);
		echo('<br>');
		$query = mysqli_query($this->connect,$sql) or exit(mysqli_error($this->connect));
		
		return $query;
	}
	
	public function close()//fermeture
	{
		mysqli_close($this->connect);//on ferme la bdd
	}
	
	public function destroy ($sid)//destruction
	{
		$sql = "DELETE FROM session
			    WHERE sess_id = '$sid' ";//on supprime la session de la bdd
		$query = mysqli_query($this->connect,$sql) or exit(mysqli_error($this->connect));
		return $query;
	}
	
	public function gc ()//nettoyage
	{
		$sql = "DELETE FROM session 
				WHERE sess_expire < ".time(); //on supprime les vieilles sessions 
				
		$query = mysqli_query($this->connect,$sql) or exit(mysqli_error($this->connect));
		
		return $query;
	}
	
}//fin de la classe
?>


Modifié par ladcandide (31 May 2014 - 11:49)
Bon, j'ai me suis créé un hébergement gratuit sur xayo.net et tout fonctionne correctement.
Donc le problème vient bien du serveur de prod... A eux de voir...

Pour ma part, je vous remercie de m'avoir suivit sur ce sujet, je vais clore car je n'ai pas le temps d'enquêter plus pour l'instant.

Laurent