i have a very specific problem regarding a custom session handler using a mysql database. I looked through other topics since there are some topics here involving custom session handler but no one of them answered my question.
I use a custom session handler in a class called “sessions”:
require_once "mySQL.php";
class sessions {
private $db;
public function __construct(){
$this->db=new mySQL('localhost', user, pw, database);
session_set_save_handler(array(&$this,"open"),
array(&$this,"close"),
array(&$this,"read"),
array(&$this,"write"),
array(&$this,"destroy"),
array(&$this,"gc"));
register_shutdown_function('session_write_close');
session_start();
}
public function read($sessionID){
$abfrage="SELECT * FROM sessions WHERE id='".$sessionID."'";
$result= $this->db->query($abfrage);
if ($result == false){
return '';
}
if (count($result) > 0){
return $result[0]["value"];
}
else{
return '';
}
}
In “mySQL.php” there is just a class “mySQL” written which creates a mysqli connection to the database. This is working and not the problem. I would like to draw the focus to the “read” routine because this seems to be the primary problem. If i now create a session via
require_once "classes/sessions.php";
$SESSION=new sessions();
$token=hash("sha256",session_id().time());
$_SESSION['token']=$token;
$_SESSION['running']=1
and write values into the session the right database value is created:
id (varchar 64) = 54ul84nhc3aimqc55efcs49js4
lastUpdated (int 11) = 1352226239
start (int 11) = 1352226233
value (varchar 20000) = token|s:64:"2b92aa848a86741ef11d800c3dce527fdcee264f50de10381941241c3d9cc9ee";running|i:1;
and even the garbage collector works fine but when i reload the page and try to echo
$_SESSION['running']
i get the error “Notice:Undefined index: running”. A debugger run informed that the above posted read routine returns 1 (which would be equal to the boolean “true”?!) instead of the value. I checked that the “sessionID” in the read routine for that case was the one in the session table, so i’m basically lost. It would be very nice if you can help me, because so far i’m already impressed of the possibilities offered by such custom session handler.
Perhaps it’s possible to pose also a side question here. Is it right that when i reload the page the constructor of sessions is called by “$SESSION=new sessions();” even when there is already a session running (however this behaviour does not change the session_id)? Or is this due to my broken session read routine?
Thank you for your help.
EDIT: I’m using PHP/5.4.4 and MySQL 5.5.25a in a xampp distribution along with phpmyAdmin 3.5.2 to set up the database. The session table is a table of format “MEMORY”, that’s why i’m using a varchar 20000 field instead of a text field. I just saw this article Why does mysql_query() return TRUE with a SELECT statement?
stating that a mysql_query returns true from time to time when the server interrupts connections suddenly. However i can’t fiddle out what may be the reason for this.
I’m adding now the mySQL class, perhaps a error in there is involved in this problem:
<?php
class mySQL
{
public $mySQLiObj;
public $lastSQLQuery;
public $lastSQLStatus;
public $lastInsertID;
public function __construct($server,$user,$password,$db,$port="3306"){
//erstelle db-objekt
$this->mySQLiObj= new mysqli($server,$user,$password,$db,$port);
if (mysqli_connect_errno()){
echo "Keine Verbindung zum MySQL-Server möglich.";
trigger_error("MYSQL-Connection-Error",E_USER_ERROR);
die();
}
//Zeichensatz auf utf8 setzen
$this->query("SET NAMES utf8");
}
public function __destruct(){
$this->mySQLiObj->close();
}
public function query($sqlQuery,$resultset=false){
$this->lastSQLQuery=$sqlQuery;
$result=$this->mySQLiObj->query($sqlQuery);
if($resultset == true){
if($result == false) {
$this->lastSQLStatus=false;
}
else
{
$this->lastSQLStatus = true;
}
return $result;
}
if($resultset == false) {
$return = $this->makeArrayResult($result);
return $return;
}
}
private function makeArrayResult($ResultObj){
if ($ResultObj==false){
//Fehler aufgetreten
$this->lastSQLStatus=false;
return false;
}
else if ($ResultObj == true) {
//UPDATE,INSERT etc. statement es wird nur true zurückgegeben
$this->lastSQLStatus = true;
$this->lastInsertID = $this->mySQLiObj->insert_id;
return true;
}
else if ($ResultObj->num_rows == 0){
//Kein Ergebnis bei SELECT,SHOW,DESCRIBE oder EXPLAIN Statement
$this->lastSQLStatus = true;
return array();
}
else {
$array = array();
while($line = $ResultObj->fetch_array(MYSQLI_ASSOC)){
array_push($array,$line);
}
$this->lastSQLStatus=true;
return $array;
}
}
}
so after a lot of try and error and looking back into the book where i got the basic layout of the session handler from i answered this question on my own.
Seems like this
was the crucial point. Instead of creating a session by explicit call one has to call
and remove the line out of the constructor in the sessions class. However it’s interesting that such weird error arises by that.
Thanks for taking a look, perhaps this helps someone.