*
sessionid for the id of the session (varchar 96)
* lifetime for the lifetime end of the session (long)
* sessiondata for the serialized session data ([long]text)
*
*
* Usage example:
* session_set_save_handler(new DBSession($db), true);
session_start();
*
* @author Stefan Daurer
* @package Mammut\Session
* @since 1.1.0.0
*/
class DBSession extends \Mammut\StrictObject implements \SessionHandlerInterface {
/** @var DB */
private $db;
private $table;
private $columns = array('sessionid','lifetime','sessiondata');
private $lifetime = 1440;
/**
* Creates a new session handler implementation
* @param DB $db a database connection
* @param string $table the name of the table, 'sessions' is used as default
* @param array $columns the column names, 'sessionid', 'lifetime' and 'sessiondata' by default
* @throws \BadMethodCallException if the number of columns given is not 0 (use defaults) or 3 (key, timestamp, data)
*/
public function __construct(DB $db, $table = 'sessions', array $columns = array()) {
$this->db = $db;
$this->table = $table;
$lifetime = ini_get('session.gc_maxlifetime');
if (!empty($lifetime))
$this->lifetime = (int) $lifetime;
if (count($columns) == 0)
return;
if (count($colums) == 2) {
$this->columns = $columns;
return;
}
throw new \BadMethodCallException('Invalid column setting');
}
public function open($save_path, $sessionid) {
// nothing to do...
return true;
}
public function read($sessionid) {
list($idCol,$ltCol,$dataCol) = $this->columns;
$select = $this->db->select();
$select->from($this->table)->columns(['dat' => $dataCol]);
$select->where(PredicateSet::newAndSet()->equalTo($idCol, new Parameter())->greaterThan($ltCol, new Parameter()));
$result = $this->db->getObjectP($select, [$sessionid, time()]);
return $result ? $result : '';
}
public function write($sessionid, $sessiondata) {
$newExp = time() + $this->lifetime;
list($idCol,$ltCol,$dataCol) = $this->columns;
$select = $this->db->select();
$select->from($this->table)->columns(['c' => SQLFunction::count()]);
$select->where([$idCol => new Parameter()]);
$iTable = $this->db->escapeTableName($this->table);
$iId = $this->db->escapeColumnName($idCol);
$iLt = $this->db->escapeColumnName($ltCol);
$iData = $this->db->escapeColumnName($dataCol);
$vSessId = $this->db->escapeValue($sessionid);
$vData = $this->db->escapeValue($sessiondata, true);
$count = $this->db->getObjectP($select, [$sessionid])->c;
if ($count) {
$sql = "UPDATE {$iTable} SET {$iLt}={$newExp}, {$iData}={$vData} WHERE {$iId}={$vSessId}";
$this->db->query($sql);
if ($this->db->getAffectedRowCount() > 0)
return true;
}
else {
$sql = "INSERT INTO {$iTable} ({$iId},{$iLt},{$iData}) VALUES ({$vSessId},{$newExp},{$vData})";
$this->db->query($sql);
if ($this->db->getAffectedRowCount() > 0)
return true;
}
return false;
}
public function close() {
$this->gc(ini_get('session.gc_maxlifetime'));
}
public function destroy($sessionid) {
list($idCol,$ltCol,$dataCol) = $this->columns;
$delete = $this->db->delete()->from($this->table)->where([$idCol => new Parameter()]);
$count = $this->db->executeP($delete, [$sessionid]);
return ($count) ? true : false;
}
public function gc($maxlifetime) {
list($idCol,$ltCol,$dataCol) = $this->columns;
$delete = $this->db->delete()->from($this->table)->where(PredicateSet::newAndSet()->lessThan($ltCol, new Parameter()));
$count = $this->db->executeP($delete, [time()]);
return $count;
}
public function __destruct() {
session_write_close();
}
}