Files
development/www/lib/CoreLibs/Create/Session.php
Clemens Schwaighofer 59da10b649 Session class update with session destroy / start wrapper
session start wrapper as protected method

session destroy wrapper with _SESSION array unset
2022-06-02 16:35:40 +09:00

372 lines
8.4 KiB
PHP

<?php
/*
* AUTHOR: Clemens Schwaighofer
* DESCRIPTION:
* start a php sesseion
* name can be given via startSession parameter
* if not set tries to read $SET_SESSION_NAME from global
* else will use default set in php.ini
*/
declare(strict_types=1);
namespace CoreLibs\Create;
class Session
{
/** @var string list for errors */
private $session_intern_error_str = '';
/**
* Start session
* startSession should be called for complete check
* If this is called without any name set before the php.ini name is
* used.
*
* @return void
*/
protected function startSessionCall(): void
{
session_start();
}
/**
* init a session, if array is empty or array does not have session_name set
* then no auto init is run
*
* @param string $session_name if set and not empty, will start session
*/
public function __construct(string $session_name = '')
{
if (!empty($session_name)) {
$this->startSession($session_name);
}
}
/**
* check if we are in CLI, we set this, so we can mock this
* Not this is just a wrapper for the static System::checkCLI call
*
* @return bool True if we are in a CLI enviroment, or false for everything else
*/
public function checkCliStatus(): bool
{
return \CoreLibs\Get\System::checkCLI();
}
/**
* Set session name call. If not valid session name, will return false
*
* @param string $session_name A valid string for session name
* @return bool True if session name is valid,
* False if not
*/
public function setSessionName(string $session_name): bool
{
if (!$this->checkValidSessionName($session_name)) {
return false;
}
session_name($session_name);
return true;
}
/**
* Return set error string, empty if none set
* Error strings are only set in the startSession method
*
* @return string Last error string
*/
public function getErrorStr(): string
{
return $this->session_intern_error_str;
}
/**
* check if session name is valid
*
* As from PHP 8.1/8.0/7.4 error
* INVALID CHARS: =,; \t\r\n\013\014
* NOTE: using . will fail even thought valid
* we allow only alphanumeric with - (dash) and 1 to 128 characters
*
* @param string $session_name any string, not null
* @return bool True for valid, False for invalid
*/
public static function checkValidSessionName(string $session_name): bool
{
// check
if (
// must only have those
!preg_match('/^[-a-zA-Z0-9]{1,128}$/', $session_name) ||
// cannot be only numbers
preg_match('/^[0-9]+$/', $session_name)
) {
return false;
}
return true;
}
/**
* start session with given session name if set
* aborts on command line or if sessions are not enabled
* also aborts if session cannot be started
* On sucess returns the session id
*
* @param string|null $session_name
* @return string|bool
*/
public function startSession(?string $session_name = null)
{
// we can't start sessions on command line
if ($this->checkCliStatus()) {
$this->session_intern_error_str = '[SESSION] No sessions in php cli';
return false;
}
// if session are OFF
if ($this->getSessionStatus() === PHP_SESSION_DISABLED) {
$this->session_intern_error_str = '[SESSION] Sessions are disabled';
return false;
}
// session_status
// initial the session if there is no session running already
if (!$this->checkActiveSession()) {
// if session name is emtpy, check if there is a global set
// this is a deprecated fallback
$session_name = $session_name ?? $GLOBALS['SET_SESSION_NAME'] ?? '';
// DEPRECTED: constant SET_SESSION_NAME is no longer used
// if set, set special session name
if (!empty($session_name)) {
// invalid session name, abort
if (!$this->checkValidSessionName($session_name)) {
$this->session_intern_error_str = '[SESSION] Invalid session name: ' . $session_name;
return false;
}
$this->setSessionName($session_name);
}
// start session
$this->startSessionCall();
}
// if we still have no active session
if (!$this->checkActiveSession()) {
$this->session_intern_error_str = '[SESSION] Failed to activate session';
return false;
}
if (false === ($session_id = $this->getSessionId())) {
$this->session_intern_error_str = '[SESSION] getSessionId did not return a session id';
}
return $session_id;
}
/**
* get current set session id or false if none started
*
* @return string|bool
*/
public function getSessionId()
{
return session_id();
}
/**
* get set session name or false if none started
*
* @return string|bool
*/
public function getSessionName()
{
return session_name();
}
/**
* Checks if there is an active session.
* Does not check if we can have a session
*
* @return bool True if there is an active session, else false
*/
public function checkActiveSession(): bool
{
if ($this->getSessionStatus() === PHP_SESSION_ACTIVE) {
return true;
} else {
return false;
}
}
/**
* unlock the session file, so concurrent AJAX requests can be done
* NOTE: after this has been called, no changes in _SESSION will be stored
* NOTE: a new session with a different name can be started after this one is called
* if problem, run ob_flush() and flush() too
*
* @return bool True und sucess, false on failure
*/
public function writeClose(): bool
{
return session_write_close();
}
/**
* Proper destroy a session
* - unset the _SESSION array
* - unset cookie if cookie on and we have not strict mode
* - destroy session
*
* @return bool
*/
public function sessionDestroy(): bool
{
$_SESSION = [];
if (
ini_get('session.use_cookies') &&
!ini_get('session.use_strict_mode')
) {
$session_name = $this->getSessionName();
if ($session_name === false) {
$session_name = '';
}
$params = session_get_cookie_params();
setcookie(
(string)$session_name,
'',
time() - 42000,
$params['path'],
$params['domain'],
$params['secure'],
$params['httponly']
);
}
return session_destroy();
}
/**
* get session status
* PHP_SESSION_DISABLED if sessions are disabled.
* PHP_SESSION_NONE if sessions are enabled, but none exists.
* PHP_SESSION_ACTIVE if sessions are enabled, and one exists.
*
* https://www.php.net/manual/en/function.session-status.php
*
* @return int See possible return int values above
*/
public function getSessionStatus(): int
{
return session_status();
}
// _SESSION set/unset methods
/**
* unset all _SESSION entries
*
* @return void
*/
public function unsetAllS(): void
{
foreach (array_keys($_SESSION ?? []) as $name) {
unset($_SESSION[$name]);
}
}
/**
* set _SESSION entry 'name' with any value
*
* @param string|int $name array name in _SESSION
* @param mixed $value value to set (can be anything)
* @return void
*/
public function setS($name, $value): void
{
$_SESSION[$name] = $value;
}
/**
* get _SESSION 'name' entry or empty string if not set
*
* @param string|int $name value key to get from _SESSION
* @return mixed value stored in _SESSION
*/
public function getS($name)
{
return $_SESSION[$name] ?? '';
}
/**
* Check if a name is set in the _SESSION array
*
* @param string|int $name Name to check for
* @return bool True for set, False fornot set
*/
public function issetS($name): bool
{
return isset($_SESSION[$name]);
}
/**
* unset one _SESSION entry 'name' if exists
*
* @param string|int $name _SESSION key name to remove
* @return void
*/
public function unsetS($name): void
{
if (isset($_SESSION[$name])) {
unset($_SESSION[$name]);
}
}
// set/get below
// ->var = value;
/**
* Undocumented function
*
* @param string|int $name
* @param mixed $value
* @return void
*/
public function __set($name, $value): void
{
$_SESSION[$name] = $value;
}
/**
* Undocumented function
*
* @param string|int $name
* @return mixed
*/
public function __get($name)
{
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
}
}
/**
* Undocumented function
*
* @param string|int $name
* @return bool
*/
public function __isset($name): bool
{
return isset($_SESSION[$name]);
}
/**
* Undocumented function
*
* @param string|int $name
* @return void
*/
public function __unset($name): void
{
if (isset($_SESSION[$name])) {
unset($_SESSION[$name]);
}
}
}
// __END__