Hello i’m trying to understand how sessions work and how does session_set_handler() works, so i’ve started build a class for session handling but i’ve encountered some problems with the write() function can you please help me solve the problem?
<?php
class Session extends Model
{
public
$connectionName = 'sessions',
$sessionsId,
$sessionsData;
public function __construct()
{
parent::__construct();
session_set_save_handler(
array($this, 'Open'),
array($this, 'Close'),
array($this, 'Read'),
array($this, 'Write'),
array($this, 'Destroy'),
array($this, 'Gc'));
session_start();
}
public function __destruct()
{
session_write_close();
}
public function Open()
{
return true;
}
public function Close()
{
return true;
}
public function Read($sessionsId)
{
$this->stmt = $this->prepare("SELECT * FROM `sessions` WHERE `id` = :sessionId");
$this->stmt->bindParam(":sessionId", $sessionsId);
$this->stmt->execute();
return $this->stmt->fetchAll();
}
public function Write($sessionsId, $sessionsData)
{
$this->stmt = $this->prepare("REPLACE INTO `sessions`.`sessions`
(`id`, `access`, `data`)
VALUES
(:sessionId, NOW(), :sessionValue)");
$this->stmt->bindParam(":sessionId", $sessionsId);
$this->stmt->bindParam(":sessionValue", $sessionsData);
$this->stmt->execute();
}
public function Destroy($sessionsId)
{
$this->stmt = $this->prepare("DELETE FROM `sessions`.`sessions` WHERE `id` = :sessionId");
$this->stmt->bindParam(":sessionId", $sessionsId);
$this->stmt->execute();
}
public function Gc()
{
$this->stmt = $this->prepare("DELETE FROM `sessions`.`sessions` WHERE `access` < NOW() - INTERVAL 1 HOUR");
$this->stmt->execute();
}
}
now the above code seems to work just fine the only problem is when i write a session in db i get the following insert:
dump from mysql
CREATE TABLE IF NOT EXISTS `sessions` (
`id` varchar(32) NOT NULL,
`access` datetime NOT NULL,
`data` text NOT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `sessions` (`id`, `access`, `data`) VALUES
('lhig71coed8ur81n85iiovje37', '2011-07-25 15:37:57', '');
As you can see the value of the session it’s not inserted i only get the session id.
on var_dump($sessionsData) i get:
"name|s:6:"Bogdan";"
and for var_dump($sessionsId) i get:
lhig71coed8ur81n85iiovje37
Can you please help? i don’t get any errors checked xampp logs setup display errors on error reporting everything i knew even in php.ini still no error anything used even try catch blocks. thank you very much for reading this and helping me out.
I found a flaw in your implementation which results in deleting any session data:
in
That function must return a string, in your case the data from the
datafield.But you’re returning an array (as it looks like – can’t specifically say because the actual database is hidden, PDO/MySQLi?).
However it’s highly likely that unserializing the session data (see
session_decode()) will fail, hence the session data will become empty and then saved again (as an empty string).This should be the cause of your problem. Fix it by returning the string data from the database.
Next to that I suspect a kind of encoding issue but I’m not entirely sure that this causes it. But just consider the following:
The session data is binary data, not text. You could change your table definition and access accordingly. In MySQL there is the
BLOBType for that, andbindParam()could be helped withPDO::PARAM_LOBdata type specifier.Probably this type of change will cure your issue. Otherwise it will make sure that you store the data un-altered which is what you want in any case. Stick to binary-safe handling for session data.