Oltre all'utilizzo dei file, esistono diversi modi per memorizzare i dati di sessione, ad esempio con Redis, Memcache, ma è anche possibile salvare i dati in un database, in questo articolo vedremo come implementare l'interfaccia SessionHandlerInterface per gestire le sessioni e memorizzare i dati in un database usando PDO ( PHP Data Objects ), l'interfaccia SessionHandlerInterface è la seguente
Codice PHP
interface SessionHandlerInterface {
/* Methods */
public close(): bool
public destroy(string $id): bool
public gc(int $max_lifetime): int|false
public open(string $path, string $name): bool
public read(string $id): string|false
public write(string $id, string $data): bool
}
ha cinque metodi open e close rispettivamente per aprire e chiudere una sessione, destroy per distruggere una sessione, read e write rispettivamente per leggere e scrivere una sessione, e infine gc per effettuare una pulizia di tutte le vecchie sessioni.
In questo esempio creeremo una classe PDOSessionHandler che implementa l'interfaccia SessionHandlerInterface con tutti i metodi che abbiamo visto in precedenza ( in particolare si presuppone che si stia eseguendo una versione di php `8.0.0` o successive ), la tabella in cui andremo a memorizzare i dati di sessione sarà così composta
Codice SQL
CREATE TABLE session (
`id` varchar(256) NOT NULL,
`name` varchar(256) NOT NULL,
`value` longtext,
`last_update` int(11) NOT NULL,
PRIMARY KEY (`id`,`name`) ) ENGINE = INNODB;
`name` è il nome del cookie che viene generato, di default è `PHPSESSID` ( se non specificato diversamente ), `id` è l'identificativo di sessione cioè il valore del cookie, `value` sono i dati che vengono salvati nella sessione, `last_update` è il timestamp dell'ultimo aggiornamento della sessione.
Questa è la classe PDOSessionHandler
Codice PHP
<?php
class PDOSessionHandler implements SessionHandlerInterface
{
private $pdo;
private $sessionName;
public function __construct(PDO $pdo){
$this->pdo = $pdo;
}
public function open($savePath, $sessionName): bool{
$this->sessionName = $sessionName;
return true;
}
public function close(): bool{
$this->pdo = null;
return true;
}
public function read($id){
$sql = "SELECT value FROM session WHERE name = :name AND id = :id";
$sth = $this->pdo->prepare($sql);
$sth->execute([":name" => $this->sessionName, ":id" => $id]);
$result = $sth->fetch(PDO::FETCH_ASSOC);
return !isset($result["value"]) ? "" : $result["value"];
}
public function write($id, $value): bool{
$sql = "SELECT value FROM session WHERE name = :name AND id = :id";
$sth = $this->pdo->prepare($sql);
$sth->execute([":name" => $this->sessionName, ":id" => $id]);
if (count($sth->fetchAll()) == 0) {
$sql =
"INSERT INTO session (id, name, value, last_update) values (:id, :name, :value, :last_update)";
} else {
$sql =
"UPDATE session SET value = :value, last_update = :last_update WHERE id = :id AND name = :name";
}
$sth = $this->pdo->prepare($sql);
return $sth->execute([
":id" => $id,
":name" => $this->sessionName,
":value" => $value,
":last_update" => strtotime(date("Y-m-d H:i:s")),
]);
}
public function destroy($id): bool{
$sql = "DELETE FROM session WHERE name = :name and id = :id";
$sth = $this->pdo->prepare($sql);
return $sth->execute([":name" => $this->sessionName, ":id" => $id]);
}
public function gc($maxlifetime){
$sql = "DELETE FROM session WHERE last_update < :lifetime";
$sth = $this->pdo->prepare($sql);
return $sth->execute([
":lifetime" => strtotime(date("Y-m-d H:i:s")) - $maxlifetime,
]);
}
}
Per utilizzare il session handler PDOSessionHandler è necessario utilizzare la funzione session_set_save_handler() che accetta come parametro di ingresso una classe che implementa l'interfaccia SessionHandlerInterface, quindi nel nostro caso procederemo nel seguente modo
Codice PHP
<?php
$username = "username";
$password = "password";
$databasename = "databasename";
$pdo = new PDO(
"mysql:dbname=$databasename;host=localhost;",
$username,
$password
);
session_set_save_handler(new PDOSessionHandler($pdo));
in questo caso sto usando un database di tipo MySQL.
Per iniziare a usare questo gestore di dati in sessione basta eseguire la funzione session_start()
Codice PHP
<?php
session_start();
in questo modo, a ogni modifica o lettura dell'array globale $_SESSION comporterà una modifica dei dati in sessione momorizzati nella tabella session che abbimao visto in precedenza, questa modalità può essere usata per condividere i dati in sessione tra più server.