API Index — Namespaces, Packages, Reports, Indices
utils.php
Table of Contents
Constants
- SID : mixed = ''
Functions
- php_session_encode_from_array() : string
- Encode an array into PHP's native
phpsession serialize format (key|serialized_valuefor each key). Matches the format produced bysession.serialize_handler = php(the default in mod_php / phpredis). - php_session_decode_to_array() : array<string, mixed>
- Decode a PHP session string back to an associative array.
- zeal_session_opened_handler() : SessionHandlerInterface|null
- Resolve the active custom session handler, guaranteeing the
SessionHandlerInterfacecontract thatopen()precedes anyread()/write()/destroy()(#369). A freshly-resolved handler —session_regenerate_id()/session_write_close()reached without a priorsession_start()in this request — was used un-open()ed, andFileSessionHandler's typed$savePathfataled on firstwrite()(breaking the textbook login fixation defence with an uncaught Error). - zeal_session_start() : bool
- zeal_valid_session_id() : bool
- Whether a session id is safe to use in a filesystem path / store key.
- zeal_session_strict_should_regenerate() : bool
session.use_strict_modeprovenance decision (#244).- zeal_session_set_save_handler() : bool
- Coroutine-mode override of
session_set_save_handler()(#295). - zeal_session_id() : string|false
- Get or set the session ID.
- zeal_session_status() : int
- Return the current session status (
PHP_SESSION_ACTIVEorPHP_SESSION_NONE). - zeal_session_name() : string
- Get or set the session name (the cookie name, e.g.
'PHPSESSID'). - zeal_session_write_close() : bool
- Write session data to the backing store and mark the session inactive.
- zeal_session_destroy() : bool
- Destroy the session and delete its backing storage.
- zeal_session_unset() : void
- Unset all session variables without destroying the session.
- zeal_session_regenerate_id() : bool
- Regenerate the session ID, optionally deleting the old session.
- zeal_session_get_cookie_params() : array{lifetime: int, path: string, domain: string, secure: bool, httponly: bool, samesite?: string}
- Get the current session cookie parameters.
- zeal_session_set_cookie_params() : void
- Set session cookie parameters.
- zeal_session_cache_limiter() : string
- Get or set the session cache limiter (e.g.
'nocache','public','private'). - zeal_session_commit() : bool
- Alias for
zeal_session_write_close()— write session data and close. - zeal_session_cache_expire() : int
- Get or set the session cache expiry in minutes.
- zeal_session_abort() : bool
- Discard in-memory session changes and reload session data from the file.
- zeal_session_encode() : string
- Encode the current session data to PHP's
phpserialize format string. - zeal_session_decode() : bool
- Decode a session data string and populate the active session.
- zeal_session_create_id() : string|false
- Create a new session ID, optionally with a
$prefix. - zeal_session_save_path() : string
- Get or set the session save path.
- zeal_session_module_name() : string
- Get or set the session module name (e.g.
'files','redis'). - zeal_session_gc() : int
- Garbage-collect expired sessions for the active storage.
Constants
SID
public
mixed
SID
= ''
Functions
php_session_encode_from_array()
Encode an array into PHP's native php session serialize format
(key|serialized_value for each key). Matches the format produced by
session.serialize_handler = php (the default in mod_php / phpredis).
php_session_encode_from_array(array<string, mixed> $data) : string
Parameters
- $data : array<string, mixed>
Return values
stringphp_session_decode_to_array()
Decode a PHP session string back to an associative array.
php_session_decode_to_array(string $data) : array<string, mixed>
Tries unserialize() first (handles the php_serialize handler format),
then falls back to parsing the native php format (key|serialized_value
pairs). All unserialize() calls use ['allowed_classes' => ['stdClass']]
— see the file-level security note above.
Parameters
- $data : string
Return values
array<string, mixed>zeal_session_opened_handler()
Resolve the active custom session handler, guaranteeing the
SessionHandlerInterface contract that open() precedes any
read()/write()/destroy() (#369). A freshly-resolved handler —
session_regenerate_id() / session_write_close() reached without a
prior session_start() in this request — was used un-open()ed, and
FileSessionHandler's typed $savePath fataled on first write()
(breaking the textbook login fixation defence with an uncaught Error).
zeal_session_opened_handler() : SessionHandlerInterface|null
open() is invoked once per request (flagged in session_params).
Return values
SessionHandlerInterface|nullzeal_session_start()
zeal_session_start() : bool
Return values
boolzeal_valid_session_id()
Whether a session id is safe to use in a filesystem path / store key.
zeal_valid_session_id(string $id) : bool
Rejects the inputs that would let an attacker-chosen PHPSESSID escape the
session save directory: empty/oversized values, NUL bytes, path separators
(/, \), and parent-directory references (..). The character set is
otherwise left permissive so a legitimate custom/legacy session id is not
rejected — the basename() applied at every sess_<id> file sink is the
belt-and-suspenders traversal guard.
Parameters
- $id : string
Return values
boolzeal_session_strict_should_regenerate()
session.use_strict_mode provenance decision (#244).
zeal_session_strict_should_regenerate(bool $strictMode, bool $clientSupplied, array<string|int, mixed> $loadedSession[, bool|null $storeEntryExists = null ]) : bool
zeal_valid_session_id() checks only the FORMAT of a client-supplied id; a
well-formed but server-never-issued id (a planted/fixated PHPSESSID) still
passes it. PHP's session.use_strict_mode=1 rejects any id the server has no
record of by minting a fresh one. The session managers reproduce that here:
after zeal_session_start() has loaded the store for a CLIENT-SUPPLIED id,
an EMPTY result means the id is unrecognised (stale / foreign / never issued)
— so it must not be honoured, and a fresh server-generated id is issued in
its place. This is the single trust check both CoSessionManager and
SessionManager consult, kept here so it is unit-testable without driving a
full request through OpenSwoole.
PHP's session.use_strict_mode rejects ids the server NEVER ISSUED. When
the caller can tell whether the id had a BACKING STORE ENTRY (file existed /
handler returned data), that is the canonical signal (ext-zealphp#2): an
issued-but-still-empty session — the cookie sent on a data-less first
visit, a redirect, any page that stores nothing — is a KNOWN id and must
NOT rotate. The old data-emptiness heuristic rotated those on EVERY
request, which (combined with the regenerate→write_close sid desync, fixed
alongside) cascaded into rotate-and-lose-every-write. The array heuristic
remains the fallback for callers that cannot determine store existence.
Parameters
- $strictMode : bool
-
App::$session_strict_mode. - $clientSupplied : bool
-
Whether the active id came from the client (cookie/query param) rather than being server-minted.
- $loadedSession : array<string|int, mixed>
-
The session data the store resolved for that id; its emptiness is the FALLBACK signal when
$storeEntryExistsis unknown. - $storeEntryExists : bool|null = null
-
Whether the id had a backing store entry at load time (
$g->session_params ['session_existed']);null= unknown.
Return values
bool —true when the id must be rotated to a fresh server id.
zeal_session_set_save_handler()
Coroutine-mode override of session_set_save_handler() (#295).
zeal_session_set_save_handler([mixed $handler = null ][, bool $register_shutdown = true ]) : bool
Native session_set_save_handler() registers with PHP's session module, which
the zeal_session_* overrides never consult — so a custom handler (Redis, etc.)
was silently ignored and sessions fell back to the inline file path. This routes
the handler to the slots the framework actually reads, in BOTH scopes:
App::$session_handler(process-wide) so every future request and worker sees it — the common boot-time call shape; and- the current coroutine's
$g->session_params['handler'](immediate) so a per-request middleware call takes effect for THIS request.
Only the object-handler form is supported (PHP's modern signature). The legacy
6-callable form and a non-handler argument are rejected (return false), as the
zeal_session_* core requires a \SessionHandlerInterface.
Parameters
- $handler : mixed = null
-
A
\SessionHandlerInterfaceinstance. - $register_shutdown : bool = true
-
Accepted for signature parity; unused (the managers own the write-close lifecycle).
Return values
bool —true when wired, false for an unsupported argument.
zeal_session_id()
Get or set the session ID.
zeal_session_id([string|null $id = null ]) : string|false
With no argument: reads the PHPSESSID (or custom session name) cookie
from $g->cookie. When no cookie is present a fresh ID is generated via
session_create_id() and stashed in $g->cookie. A malformed inbound ID
(path traversal, NUL, oversized) is silently replaced with a fresh one.
NOTE: this function only validates id FORMAT. The session.use_strict_mode
PROVENANCE check (rotating a well-formed but never-issued id that loads an
empty session — #244) lives in the session managers, which call
zeal_session_strict_should_regenerate() after the store has been read.
Parameters
- $id : string|null = null
-
Pass a string to set the session ID explicitly.
Return values
string|false —The current (or newly-set) session ID.
zeal_session_status()
Return the current session status (PHP_SESSION_ACTIVE or PHP_SESSION_NONE).
zeal_session_status() : int
Mode-aware: in superglobals mode inspects $GLOBALS['_SESSION']; in
coroutine mode checks whether the typed $g->session slot is initialised
(it is unset() by zeal_session_write_close() / zeal_session_destroy()
to mark a session inactive).
Return values
intzeal_session_name()
Get or set the session name (the cookie name, e.g. 'PHPSESSID').
zeal_session_name([string|null $name = null ]) : string
Stored per-request in $g->session_params['name'].
Parameters
- $name : string|null = null
-
Pass
nullto read the current value.
Return values
string —The current (or newly-set) session name.
zeal_session_write_close()
Write session data to the backing store and mark the session inactive.
zeal_session_write_close() : bool
Coroutine-safe replacement for PHP's session_write_close(). Performs a
read-merge-write under flock(LOCK_EX) (file backend) or an optimistic
WATCH/MULTI/EXEC retry loop (custom \SessionHandlerInterface) to
guard against concurrent-coroutine last-write-wins data loss on the same
session ID. The merge is shallow — top-level keys added by a concurrent
request survive, but conflicting nested arrays are last-write-wins.
After writing, $g->session (coroutine mode) or $GLOBALS['_SESSION']
(superglobals mode) is unset() so zeal_session_status() returns
PHP_SESSION_NONE for the remainder of the request.
Return values
boolzeal_session_destroy()
Destroy the session and delete its backing storage.
zeal_session_destroy() : bool
Deletes the session file (or calls \SessionHandlerInterface::destroy() for
custom backends), removes $g->session and $_SESSION, and clears the
session cookie from $g->cookie. Sets $g->_session_started to false.
Return values
boolzeal_session_unset()
Unset all session variables without destroying the session.
zeal_session_unset() : void
Resets $g->session to [] and, in superglobals mode, also clears
$GLOBALS['_SESSION']. The session file / backend entry is NOT deleted —
call zeal_session_destroy() to remove it entirely.
zeal_session_regenerate_id()
Regenerate the session ID, optionally deleting the old session.
zeal_session_regenerate_id([bool $delete_old_session = false ]) : bool
Coroutine-safe replacement for PHP's session_regenerate_id(). Copies the
current in-memory session data to the new ID via the active backend (custom
\SessionHandlerInterface or file), then emits a fresh Set-Cookie header
so the client switches to the new ID. Gated by App::$session_lifecycle
and session.use_cookies — same guards as zeal_session_start().
Parameters
- $delete_old_session : bool = false
-
When
true, the old session file/entry is deleted.
Return values
boolzeal_session_get_cookie_params()
Get the current session cookie parameters.
zeal_session_get_cookie_params() : array{lifetime: int, path: string, domain: string, secure: bool, httponly: bool, samesite?: string}
Returns the array stored in $g->session_params['cookie_params'], falling
back to safe defaults (path='/', httponly=true, samesite='Lax').
Return values
array{lifetime: int, path: string, domain: string, secure: bool, httponly: bool, samesite?: string}zeal_session_set_cookie_params()
Set session cookie parameters.
zeal_session_set_cookie_params(int|array<string, mixed> $lifetime_or_options[, string $path = null ][, string $domain = null ][, bool $secure = null ][, bool $httponly = null ]) : void
Accepts either the positional-args form (PHP < 8.0 style) or an options
array (PHP 8.0+ session_set_cookie_params(array $options) style). Both
are merged over the defaults ['lifetime'=>0, 'path'=>'/', 'domain'=>'', 'secure'=>false, 'httponly'=>false, 'samesite'=>'Lax'].
Parameters
- $lifetime_or_options : int|array<string, mixed>
-
Integer lifetime in seconds, or an options array.
- $path : string = null
- $domain : string = null
- $secure : bool = null
- $httponly : bool = null
zeal_session_cache_limiter()
Get or set the session cache limiter (e.g. 'nocache', 'public', 'private').
zeal_session_cache_limiter([string|null $cache_limiter = null ]) : string
Stored per-request in $g->cache_limiter. Defaults to 'nocache'.
Parameters
- $cache_limiter : string|null = null
-
Pass
nullto read the current value.
Return values
stringzeal_session_commit()
Alias for zeal_session_write_close() — write session data and close.
zeal_session_commit() : bool
Mirrors PHP's session_commit(), which is itself an alias of
session_write_close().
Return values
boolzeal_session_cache_expire()
Get or set the session cache expiry in minutes.
zeal_session_cache_expire([int|null $cache_expire = null ]) : int
Stored per-request in $g->cache_expire. Defaults to 180 when not set.
Parameters
- $cache_expire : int|null = null
-
Pass
nullto read the current value.
Return values
intzeal_session_abort()
Discard in-memory session changes and reload session data from the file.
zeal_session_abort() : bool
Mirrors PHP's session_abort(): any writes to $g->session or
$_SESSION since the last session_start() are thrown away, and the
session data is re-read from the session file on disk. Returns true always.
Return values
boolzeal_session_encode()
Encode the current session data to PHP's php serialize format string.
zeal_session_encode() : string
Reads from $GLOBALS['_SESSION'] in superglobals mode, or from
RequestContext::instance()->session in coroutine mode.
Return values
stringzeal_session_decode()
Decode a session data string and populate the active session.
zeal_session_decode(string $data) : bool
Mirrors PHP's session_decode(): parses $data via
php_session_decode_to_array() and stores the result in both $g->session
and $GLOBALS['_SESSION'] (in superglobals mode). Returns false when
$data is empty or decodes to an empty array.
Parameters
- $data : string
Return values
boolzeal_session_create_id()
Create a new session ID, optionally with a $prefix.
zeal_session_create_id([string $prefix = '' ]) : string|false
Thin wrapper around PHP's session_create_id().
Parameters
- $prefix : string = ''
-
Optional prefix prepended to the generated ID.
Return values
string|false —The new session ID, or false on failure.
zeal_session_save_path()
Get or set the session save path.
zeal_session_save_path([string|null $path = null ]) : string
Stored per-request in $g->session_params['save_path']. Defaults to
'/var/lib/php/sessions' when not set.
Parameters
- $path : string|null = null
-
Pass
nullto read the current value.
Return values
string —The current (or newly-set) save path.
zeal_session_module_name()
Get or set the session module name (e.g. 'files', 'redis').
zeal_session_module_name([string|null $module = null ]) : string
Stored per-request in $g->session_module_name. Defaults to 'files'
when not set. This is a ZealPHP-internal tracking field; the actual
backend is determined by the registered \SessionHandlerInterface.
Parameters
- $module : string|null = null
-
Pass
nullto read the current value.
Return values
stringzeal_session_gc()
Garbage-collect expired sessions for the active storage.
zeal_session_gc(int $maxlifetime) : int
ZealPHP replaced PHP's probabilistic per-request GC (session.gc_probability)
with deterministic, explicit collection — but nothing called it, so on a
long-lived worker sess_* files (default storage) accumulated until inodes
exhausted, and a leaked/abandoned PHPSESSID stayed replayable forever.
App::run() now schedules this on a worker-0 timer (see
App::registerSessionGc()).
A registered SessionHandlerInterface owns its own GC (Redis/Table handlers
already expire rows server-side); the default inline file path sweeps
sess_* files whose mtime is older than $maxlifetime seconds.
Parameters
- $maxlifetime : int
-
Seconds of inactivity after which a session expires.
Return values
int —Number of file entries removed (handler backends return their own count, or 0).