257 lines
7.8 KiB
PHP
257 lines
7.8 KiB
PHP
|
<?php
|
||
|
namespace nur;
|
||
|
|
||
|
/**
|
||
|
* Class session: gestion des sessions
|
||
|
*/
|
||
|
class session {
|
||
|
/** durée de session par défaut: 24 minutes */
|
||
|
const DURATION = 1440;
|
||
|
|
||
|
/** @var int */
|
||
|
protected static $duration;
|
||
|
|
||
|
/** obtenir la durée d'une session en secondes. */
|
||
|
static final function get_duration(): int {
|
||
|
$duration = self::$duration;
|
||
|
if ($duration === null) $duration = static::DURATION;
|
||
|
return $duration;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* spécifier la durée d'une session en secondes.
|
||
|
* cette méthode doit être appelée avant start()
|
||
|
*/
|
||
|
static final function set_duration(int $duration): void {
|
||
|
self::$duration = $duration;
|
||
|
}
|
||
|
|
||
|
/** vérifier si la session a été démarrée. */
|
||
|
static final function started(): bool {
|
||
|
return session_status() == PHP_SESSION_ACTIVE;
|
||
|
}
|
||
|
|
||
|
private static $started_once = false;
|
||
|
|
||
|
/** vérifier si la session a été démarrée au moins une fois */
|
||
|
static final function started_once(): bool {
|
||
|
return self::$started_once;
|
||
|
}
|
||
|
|
||
|
/** nom de la variable de session qui indique quand elle a été créée. */
|
||
|
const SESSION_CREATION_TIME = "nur\\session_creation_time";
|
||
|
|
||
|
/**
|
||
|
* démarrer la session si nécessaire. étendre la durée du cookie de session
|
||
|
* de la valeur get_duration()
|
||
|
*
|
||
|
* la page est automatiquement configurée par PHP pour ne pas être mise en
|
||
|
* cache, il est donc inutile d'utiliser {@link http::no_cache()}
|
||
|
*
|
||
|
* retourner true si la session vient d'être créée, false si elle a été
|
||
|
* chargée depuis le disque
|
||
|
*/
|
||
|
static final function start(): bool {
|
||
|
if (!self::started()) {
|
||
|
$duration = self::get_duration();
|
||
|
$can_set_cookies = !headers_sent();
|
||
|
if ($can_set_cookies) {
|
||
|
# durée initiale du cookie
|
||
|
session_set_cookie_params($duration);
|
||
|
}
|
||
|
session_start([
|
||
|
"gc_maxlifetime" => $duration,
|
||
|
]);
|
||
|
self::$started_once = true;
|
||
|
|
||
|
$creation_time = self::get(self::SESSION_CREATION_TIME, false);
|
||
|
if (!$creation_time) {
|
||
|
# création initiale
|
||
|
self::set(self::SESSION_CREATION_TIME, time());
|
||
|
return true;
|
||
|
} elseif ($can_set_cookies) {
|
||
|
# étendre la durée du cookie
|
||
|
$params = session_get_cookie_params();
|
||
|
setcookie(session_name(), session_id(), time() + $duration, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* enregistrer la session, la fermer et libérer son verrou.
|
||
|
*
|
||
|
* cette fonction peut être appelée avant une opération longue si on n'a plus
|
||
|
* besoin de la session.
|
||
|
*
|
||
|
* retourn true si la session a été fermée, false sinon.
|
||
|
*/
|
||
|
static final function close(): bool {
|
||
|
if (self::started()) {
|
||
|
session_write_close();
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* vider la session de toutes ses variables ($unset_only==true) ou la détruire
|
||
|
* ($unset_only==false). en cas de destruction de la session, supprimer aussi
|
||
|
* le cookie de session
|
||
|
*
|
||
|
* si $unset_only==true, refaire la variable SESSION_CREATION_TIME
|
||
|
*/
|
||
|
static final function destroy(bool $unset_only=false, bool $clear_cookie=true): void {
|
||
|
self::start();
|
||
|
if ($unset_only) {
|
||
|
session_unset();
|
||
|
self::set(self::SESSION_CREATION_TIME, time());
|
||
|
} else {
|
||
|
$can_set_cookies = !headers_sent();
|
||
|
if ($clear_cookie && $can_set_cookies && ini_get("session.use_cookies")) {
|
||
|
$params = session_get_cookie_params();
|
||
|
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
|
||
|
}
|
||
|
session_destroy();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Vider la session de toutes les clés spécifiées dans $keys qui ne sont pas
|
||
|
* mentionnées dans $keeps
|
||
|
*
|
||
|
* Si $keys vaut null, toutes les clés sont supprimées comme avec destroy(true)
|
||
|
* notamment, cela signifie que la variable SESSION_CREATION_TIME est refaite
|
||
|
*/
|
||
|
static final function unset_keys(?array $keys, ?array $keeps=null): void {
|
||
|
$update_session_creation_time = false;
|
||
|
if ($keys === null) {
|
||
|
$keys = array_keys($_SESSION);
|
||
|
$update_session_creation_time = true;
|
||
|
}
|
||
|
if ($keeps !== null) $keys = array_diff($keys, $keeps);
|
||
|
foreach ($keys as $key) {
|
||
|
unset($_SESSION[$key]);
|
||
|
}
|
||
|
if ($update_session_creation_time) {
|
||
|
self::set(self::SESSION_CREATION_TIME, time());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Vider la session de toutes les clés spécifiées. */
|
||
|
static final function unset_key(...$keys): void {
|
||
|
self::unset_keys($keys);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Dans la session, ne garder que les clés spécifiées.
|
||
|
*
|
||
|
* Refaire la variable SESSION_CREATION_TIME
|
||
|
*/
|
||
|
static final function keep_key(...$keeps): void {
|
||
|
self::unset_keys(null, $keeps);
|
||
|
}
|
||
|
|
||
|
/** vérifier si la session est démarrée et si la clé spécifiée existe. */
|
||
|
static final function has($key): bool {
|
||
|
if ($key === null || $key === false) return false;
|
||
|
return isset($_SESSION) && array_key_exists($key, $_SESSION);
|
||
|
}
|
||
|
|
||
|
/** obtenir la valeur associée à la clé spécifiée si la session est démarrée. */
|
||
|
static final function get(string $key, $default=null) {
|
||
|
if (!isset($_SESSION)) return $default;
|
||
|
return A::get($_SESSION, $key, $default);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* mettre à jour la valeur d'une variable de session.
|
||
|
*
|
||
|
* ne pas chercher à savoir si la session est démarrée ou non
|
||
|
*/
|
||
|
static final function set(string $key, $value): void {
|
||
|
$_SESSION[$key] = $value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* comme {@link set()} mais rouvrir automatiquement la session si nécessaire,
|
||
|
* à condition qu'elle aie déjà été ouverte une fois
|
||
|
*/
|
||
|
static final function setx(string $key, $value): void {
|
||
|
$close = !self::started() && self::started_once();
|
||
|
if ($close) self::start();
|
||
|
self::set($key, $value);
|
||
|
if ($close) self::close();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* supprimer une variable de session.
|
||
|
*
|
||
|
* ne pas chercher à savoir si la session est démarrée ou non
|
||
|
*/
|
||
|
static final function del(string $key): void {
|
||
|
unset($_SESSION[$key]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* comme {@link del()} mais rouvrir automatiquement la session si nécessaire,
|
||
|
* à condition qu'elle aie déjà été ouverte une fois
|
||
|
*/
|
||
|
static final function delx(string $key): void {
|
||
|
$close = !self::started() && self::started_once();
|
||
|
if ($close) self::start();
|
||
|
self::del($key);
|
||
|
if ($close) self::close();
|
||
|
}
|
||
|
|
||
|
/** vérifier si chemin de clé spécifié existe dans la session. */
|
||
|
static final function phas($pkey): bool {
|
||
|
return isset($_SESSION) && A::phas($_SESSION, $pkey);
|
||
|
}
|
||
|
|
||
|
/** obtenir la valeur associée au chemin de clé spécifié si la session est démarrée. */
|
||
|
static final function pget($pkey, $default=null) {
|
||
|
return isset($_SESSION) && A::pget($_SESSION, $pkey, $default);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* mettre à jour la valeur correspondant au chemin de clé spécifié.
|
||
|
*
|
||
|
* ne pas chercher à savoir si la session est démarrée ou non
|
||
|
*/
|
||
|
static final function pset($pkey, $value): void {
|
||
|
A::pset($_SESSION, $pkey, $value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* comme {@link pset()} mais rouvrir automatiquement la session si nécessaire,
|
||
|
* à condition qu'elle aie déjà été ouverte une fois
|
||
|
*/
|
||
|
static final function psetx(string $key, $value): void {
|
||
|
$close = !self::started() && self::started_once();
|
||
|
if ($close) self::start();
|
||
|
self::pset($key, $value);
|
||
|
if ($close) self::close();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* supprimer la variable au chemin de clé spécifié.
|
||
|
*
|
||
|
* ne pas chercher à savoir si la session est démarrée ou non
|
||
|
*/
|
||
|
static final function pdel($pkey): void {
|
||
|
A::pdel($_SESSION, $pkey);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* comme {@link pdel()} mais rouvrir automatiquement la session si nécessaire,
|
||
|
* à condition qu'elle aie déjà été ouverte une fois
|
||
|
*/
|
||
|
static final function pdelx(string $key): void {
|
||
|
$close = !self::started() && self::started_once();
|
||
|
if ($close) self::start();
|
||
|
self::pdel($key);
|
||
|
if ($close) self::close();
|
||
|
}
|
||
|
}
|