Alpha ZealPHP is early-stage and under active development. APIs may change between minor versions until v1.0. Feedback and bug reports welcome on GitHub.
API Index — Namespaces, Packages, Reports, Indices

utils.php

Table of Contents

Classes

LogSinkRegistry
Per-worker registry for the async-log sinks and their consumer-spawn guard.

Functions

get()  : mixed
Read a value from $_GET by key.
env_flag()  : bool
Read a boolean environment variable using ZealPHP's truthiness convention.
bench_mode_enabled()  : bool
Whether benchmark mode is active (ZEALPHP_BENCH_MODE env flag).
site_url()  : string
Absolute base URL for the ZealPHP OSS site.
site_host()  : string
Return just the host component of site_url().
async_logging_enabled()  : bool
Whether async (coroutine-channel-backed) logging is enabled.
zealphp_log_dir_candidates()  : array<int, string>
Ordered list of directories ZealPHP will try for its logs + PID files, most preferred first. Pure (no I/O, no memoization) so it is unit-testable; the actual pick — the first candidate that is writable or creatable — happens in resolve_log_dir().
resolve_log_dir()  : string|null
Resolve the first writable log directory from zealphp_log_dir_candidates().
cgroup_cpu_quota()  : float|null
The container's CPU allowance from its cgroup CPU quota, or null when there is no quota (unlimited, or not running under a limited cgroup).
default_worker_count()  : int
Default HTTP worker count for a bare php app.php (no ZEALPHP_WORKERS), capped to the container's cgroup CPU quota.
debug_logging_enabled()  : bool
Whether debug logging is enabled.
access_logging_enabled()  : bool
Whether access logging is enabled.
log_file_for()  : string|null
Resolve the absolute path for a named log file.
log_sink_for()  : Channel|null
log_write()  : void
Write a log line to the appropriate sink for $kind.
coprocess()  : mixed
Run a closure in a throwaway child process that HAS the coroutine scheduler, even though the caller does not. This is the escape hatch for parallel I/O from a coroutine-scheduler-OFF worker — i.e. superglobals(true) / enableCoroutine(false) mode (the Symfony/FPM-style lifecycle, where running coroutines in the main worker would race process-wide $_GET/$_POST/$_SESSION and shared framework singletons).
coproc()  : mixed
Thin alias for coprocess() — same fork-a-coroutine-child semantics, so it shares coprocess()'s untestability (forks a child process; only valid in the superglobals(true)+enableCoroutine(false) mode the coverage gate excludes).
jTraceEx()  : string
Produce a Java-style exception trace string.
zapi()  : string
Return the basename (without .php extension) of the calling API file.
elog()  : void
Log a debug message with caller location.
zlog()  : void
Log a structured message to zlog.log with request context.
get_config()  : mixed
Read a site configuration value by key.
get_current_render_time()  : float
Get the current render time since request received and started processing.
indent()  : string
Indent the given text with the given number of spaces.
purify_array()  : array<int|string, mixed>
Convert an iterator or object into an array via JSON round-trip.
uniqidReal()  : string
Generates a unique identifier of a specified length.
access_log()  : void
Write an access log line for the current request.
response_add_header()  : void
Add a header to the current response.
response_set_status()  : void
Sets the HTTP response status code.
response_headers_list()  : array<int, array{0: string, 1: string}>
Retrieves all the response headers.
setcookie()  : bool
Set a response cookie (uopz override of PHP's built-in setcookie()).
setrawcookie()  : bool
Set a raw (URL-encoded) response cookie (uopz override of PHP's built-in setrawcookie()).
header()  : false|void
Set a response header (uopz override of PHP's built-in header()).
http_response_code()  : int|null
Get or set the HTTP response status code (uopz override of PHP's built-in http_response_code()).
zeal_putenv()  : bool
Per-coroutine putenv() — stores the assignment in the request-scoped RequestContext ($g->memo['_env']), which is isolated per coroutine in Mode 4, instead of the process-wide environment. Pairs with getenv().
zeal_getenv()  : string|array<string, string>|false
Per-coroutine getenv() — reads the request-scoped env first (set via putenv()), then the process environment captured at boot (App::$boot_env). No-arg form returns the merged map. $local_only returns only request-scoped variables (matches the native signature).
zeal_shell_exec()  : string|null
Coroutine-safe shell_exec() shim — routes through App::exec().
zeal_system()  : string
Coroutine-safe system() shim — routes through App::exec().
zeal_passthru()  : void
Coroutine-safe passthru() shim — routes through App::exec().
zeal_exec()  : string
Coroutine-safe exec() shim — routes through App::exec().
headers_list()  : array<int, string>
Return all outbound response headers as formatted strings (uopz override of headers_list()).
headers_sent()  : bool
Check whether response headers have already been sent (uopz override of headers_sent()).
header_remove()  : void
Remove a previously set response header (uopz override of header_remove()).
flush()  : void
Force the current output buffer to the client (uopz override of flush()).
ob_flush()  : void
Override of ob_flush() — floor-aware.
ob_end_flush()  : void
Override of ob_end_flush() — floor-aware.
ob_implicit_flush()  : void
Apache mod_php ob_implicit_flush() compatibility shim.
phpinfo()  : bool
mod_php-parity phpinfo(): render a self-contained HTML document instead of the CLI SAPI's plain-text dump. Matches the native signature — echoes output and returns true. Wired via uopz in App::__construct(); the renderer lives in \ZealPHP\Diagnostics\PhpInfo.
php_sapi_name()  : string
mod_php-parity php_sapi_name(): under the CLI SAPI this natively returns "cli", which legacy apps branch on to disable web-only behavior. When an app opts in via App::sapiName('apache2handler') (or 'fpm-fcgi'), this returns the configured value so such code takes its web path. Default (App::$sapi_name === null) returns the real PHP_SAPI — zero behavior change unless explicitly configured.
filter_input()  : mixed
mod_php-parity filter_input(): native filter_input() reads PHP's internal SAPI request tables, which OpenSwoole never populates (so it returns null under CLI).
filter_input_array()  : array<string, mixed>
mod_php-parity filter_input_array(): the array counterpart of filter_input().
header_register_callback()  : bool
mod_php-parity header_register_callback(): native PHP fires the callback when the SAPI is about to send headers — which never happens the normal way under OpenSwoole. ZealPHP stores it per-request (coroutine-safe, in $g->memo) and invokes it once just before the buffered response headers are flushed, so header() calls inside the callback still land. Last registration wins (matches native, which keeps a single callback). Returns false if there's no request context (e.g. called outside a request).
error_log()  : bool
mod_php-parity error_log(): under the CLI SAPI native error_log() writes to stderr / the php.ini error_log path. ZealPHP routes message_type 0 (system logger) and 4 (SAPI logger) into the framework's async log (debug.log, or stderr if logging is disabled) so legacy error_log() calls land where the rest of the app's diagnostics go — the "we have elog for error_log" contract.
apache_request_headers()  : array<string, string>
Apache mod_php getallheaders() / apache_request_headers() — return all inbound request headers with canonical (Hyphen-Capitalized) case.
getallheaders()  : array<string, string>
Alias for apache_request_headers() — return all inbound request headers.
apache_response_headers()  : array<string, string>
Apache mod_php apache_response_headers() — return currently queued outbound headers.
apache_setenv()  : bool
Apache mod_php per-request env table setter (apache_setenv()).
apache_getenv()  : string|false
Apache mod_php per-request env table getter (apache_getenv()).
apache_note()  : string
Apache mod_php apache_note() — per-request note table. Returns previous value.
virtual()  : bool
Apache mod_php virtual() — performs an internal subrequest.
set_time_limit()  : bool
set_time_limit() compatibility shim.
ignore_user_abort()  : int
ignore_user_abort() compatibility shim (uopz override).
connection_status()  : int
Return the connection status for the current request.
connection_aborted()  : int
Return 1 when the client connection has been aborted, 0 otherwise.
output_add_rewrite_var()  : bool
Apache's URL-rewrite output handler — not used in ZealPHP. No-op returning false.
output_reset_rewrite_vars()  : bool
Apache's URL-rewrite output handler reset — not used in ZealPHP. No-op returning true.
is_uploaded_file()  : bool
is_uploaded_file() compatibility shim (uopz override).
_zealphp_tmp_name_matches()  : bool
Recursively test whether $filename is one of the temp-path leaves in a field-major $_FILES[...]['tmp_name'] value (scalar or nested array).
move_uploaded_file()  : bool
move_uploaded_file() compatibility shim (uopz override).
set_error_handler()  : callable|null
Per-request set_error_handler() (uopz override).
restore_error_handler()  : bool
Pop the most recently registered per-request error handler.
set_exception_handler()  : callable|null
Per-request set_exception_handler() (uopz override).
restore_exception_handler()  : bool
Pop the most recently registered per-request exception handler.
register_shutdown_function()  : void
Per-request shutdown function (uopz override of register_shutdown_function()).
error_reporting()  : int
Per-coroutine error_reporting() (uopz override).

Functions

get()

Read a value from $_GET by key.

get(string $key[, mixed $default = null ]) : mixed
Parameters
$key : string
$default : mixed = null

env_flag()

Read a boolean environment variable using ZealPHP's truthiness convention.

env_flag(string $name, bool $default) : bool

Returns $default when the variable is unset or empty. Otherwise, returns false when the value is one of '0', 'false', 'off', 'no', or 'none' (case-insensitive); returns true for everything else.

Parameters
$name : string
$default : bool
Return values
bool

bench_mode_enabled()

Whether benchmark mode is active (ZEALPHP_BENCH_MODE env flag).

bench_mode_enabled() : bool

Bench mode disables all logging to avoid I/O overhead skewing results. The result is memoised after the first call.

Return values
bool

site_url()

Absolute base URL for the ZealPHP OSS site.

site_url([string $path = '' ]) : string

Resolution order:

  1. ZEALPHP_SITE_URL env var.
  2. ZEALPHP_SITE_HOST env var (scheme https:// prepended if absent).
  3. Hard-coded fallback https://php.zeal.ninja.

When $path is non-empty it is appended with a single / separator. The result is memoised after the first call.

Parameters
$path : string = ''
Return values
string

site_host()

Return just the host component of site_url().

site_host() : string

Falls back to the full site_url() string when parse_url() cannot extract a host (e.g. a bare domain without scheme).

Return values
string

async_logging_enabled()

Whether async (coroutine-channel-backed) logging is enabled.

async_logging_enabled() : bool

Controlled by the ZEALPHP_LOG_ASYNC env flag (default true). The result is memoised after the first call.

Return values
bool

zealphp_log_dir_candidates()

Ordered list of directories ZealPHP will try for its logs + PID files, most preferred first. Pure (no I/O, no memoization) so it is unit-testable; the actual pick — the first candidate that is writable or creatable — happens in resolve_log_dir().

zealphp_log_dir_candidates() : array<int, string>

Order:

  1. $ZEALPHP_LOG_DIR — explicit override, when set.
  2. /tmp/zealphp — the shared default, kept first for BC (used whenever the current user can create/write it: single-user box, root, or fresh box).
  3. Per-user fallbacks for the collision case where /tmp/zealphp already exists owned by ANOTHER user (e.g. root started a server there first), so this user cannot write it: $XDG_RUNTIME_DIR/zealphp, then a uid/user- suffixed temp dir (sys_get_temp_dir()/zealphp-<uid>). These keep us off a non-writable /tmp/zealphp without polluting the project tree, and resolve deterministically so start and stop/status agree on the same dir.
  4. Project-tree last resorts (./tmp/zealphp, ./logs/zealphp).
Return values
array<int, string>

resolve_log_dir()

Resolve the first writable log directory from zealphp_log_dir_candidates().

resolve_log_dir() : string|null

Creates the directory (with 0775 permissions, recursively) if it does not yet exist. Memoises the result so the filesystem is only probed once per worker lifetime. Returns null when no candidate is writable or creatable.

Return values
string|null

cgroup_cpu_quota()

The container's CPU allowance from its cgroup CPU quota, or null when there is no quota (unlimited, or not running under a limited cgroup).

cgroup_cpu_quota() : float|null

Reads cgroup v2 (/sys/fs/cgroup/cpu.max = "quota period") first, then v1 (cpu.cfs_quota_us / cpu.cfs_period_us). Returns quota ÷ period as a float (e.g. 6.0 for "600000 100000"); null for "max" / unset / unreadable.

Return values
float|null

default_worker_count()

Default HTTP worker count for a bare php app.php (no ZEALPHP_WORKERS), capped to the container's cgroup CPU quota.

default_worker_count([int $preferred = 4 ]) : int

OpenSwoole's own default when worker_num is unset is swoole_cpu_num() = the HOST cpu count — so a bare boot in a CPU-limited Docker container over-spawns (e.g. 24 workers on a 4–6 CPU container) and gets OOM-killed. Returns max(1, min($preferred, floor(cgroup_quota))); when there is no cgroup quota it returns the conservative $preferred (NOT the host count).

Parameters
$preferred : int = 4

desired worker count when unconstrained (default 4)

Return values
int

debug_logging_enabled()

Whether debug logging is enabled.

debug_logging_enabled() : bool

Always false in bench mode. Controlled by ZEALPHP_DEBUG_LOG or the legacy ZEALPHP_ELOG env var (default true when neither is set). The result is memoised after the first call.

Return values
bool

access_logging_enabled()

Whether access logging is enabled.

access_logging_enabled() : bool

Always false in bench mode. Controlled by the ZEALPHP_ACCESS_LOG env flag (default true). The result is memoised after the first call.

Return values
bool

log_file_for()

Resolve the absolute path for a named log file.

log_file_for(string $kind) : string|null

$kind is one of 'access', 'zlog', or 'debug'. Checks (in order):

  1. Kind-specific env var (ZEALPHP_ACCESS_LOG_FILE, ZEALPHP_ZLOG_FILE, ZEALPHP_DEBUG_LOG_FILE).
  2. ZEALPHP_LOG_FILE (generic override, all kinds).
  3. resolve_log_dir() + kind-specific filename (access.log, zlog.log, debug.log).

Returns null when no writable log directory can be found. Results are memoised per kind.

Parameters
$kind : string
Return values
string|null

log_sink_for()

log_sink_for(string $path) : Channel|null
Parameters
$path : string
Return values
Channel|null

log_write()

Write a log line to the appropriate sink for $kind.

log_write(string $message[, string $kind = 'debug' ]) : void

Pushes to the async Channel sink when one is available (non-blocking, coroutine-safe). Falls through to a synchronous fopen/fwrite when called outside a coroutine or when the channel push fails. Writes to php://stderr as a last resort when no log file can be resolved.

Note: uses php://stderr directly (not error_log()) in fallback paths because error_log() is uopz-overridden to route into this very function — calling it would recurse infinitely.

Parameters
$message : string
$kind : string = 'debug'

coprocess()

Run a closure in a throwaway child process that HAS the coroutine scheduler, even though the caller does not. This is the escape hatch for parallel I/O from a coroutine-scheduler-OFF worker — i.e. superglobals(true) / enableCoroutine(false) mode (the Symfony/FPM-style lifecycle, where running coroutines in the main worker would race process-wide $_GET/$_POST/$_SESSION and shared framework singletons).

coprocess(callable $taskLogic[, bool $wait = true ]) : mixed

The child is spawned with OpenSwoole's coroutine runtime enabled, so inside $taskLogic you can go() + Channel + hooked I/O (curl, file_get_contents, PDO over the network, Co\System::exec, ...) and they run concurrently. The call BLOCKS until the child finishes (when $wait is true) and returns whatever the child echoed — so serialise structured results (json_encode in the child, json_decode in the caller).

Cost & caveats:

  • One proc-style fork per call (~ms). Worth it when a request needs N genuinely-parallel slow I/O calls; not worth it for a single call or CPU-bound work.
  • The child is a FRESH process — it does NOT inherit your framework container, DB connection pool, or request state. Pass everything it needs as captured variables; do raw I/O inside (it can't reach Symfony services / Doctrine's managed connection).
  • Refused when superglobals(false) (coroutine mode) — there you already have a scheduler, so just go() directly.

Example (3 parallel HTTP fetches from a sequential worker):

$json = coprocess(function () {
    $chan = new \OpenSwoole\Coroutine\Channel(3);
    foreach (['a','b','c'] as $svc) {
        go(function () use ($svc, $chan) {
            $chan->push([$svc => file_get_contents("https://api/$svc")]);
        });
    }
    $out = [];
    for ($i = 0; $i < 3; $i++) { $out += $chan->pop(); }
    echo json_encode($out);            // returned to the caller as a string
});
$data = json_decode($json, true);
Parameters
$taskLogic : callable

The logic to run in the coroutine-enabled child. Receives the OpenSwoole\Process as its argument.

$wait : bool = true

Whether to block until the child completes. Default true.

Return values
mixed

The child's echoed output (string) when $wait is true.

coproc()

Thin alias for coprocess() — same fork-a-coroutine-child semantics, so it shares coprocess()'s untestability (forks a child process; only valid in the superglobals(true)+enableCoroutine(false) mode the coverage gate excludes).

coproc(callable $taskLogic) : mixed
Parameters
$taskLogic : callable
Tags
codeCoverageIgnore

jTraceEx()

Produce a Java-style exception trace string.

jTraceEx(Throwable $e[, array<int, string>|null $seen = null ]) : string
Parameters
$e : Throwable
$seen : array<int, string>|null = null

array passed to recursive calls to accumulate trace lines already seen; leave as null when calling this function

Return values
string

of array strings, one entry per trace line

zapi()

Return the basename (without .php extension) of the calling API file.

zapi() : string

Used inside api/ handlers to obtain the endpoint name for logging without hard-coding the filename. Reads one frame from debug_backtrace().

Return values
string

elog()

Log a debug message with caller location.

elog(string $message[, string $tag = "*" ][, int $limit = 1 ]) : void

Writes to the debug log (debug.log) when debug_logging_enabled() is true. Messages tagged 'wordpress' are silently suppressed to avoid noise from WordPress's verbose internal logging.

Parameters
$message : string

The message to log.

$tag : string = "*"

The tag to associate with the log message. Default "*".

$limit : int = 1

Stack depth passed to debug_backtrace(). Default 1.

zlog()

Log a structured message to zlog.log with request context.

zlog(mixed $log[, string $tag = "system" ][, mixed $filter = null ][, bool $invert_filter = false ]) : void

Writes caller file/line, request URL, request ID, and render timer alongside the message. Valid $tag values: 'system', 'fatal', 'error', 'warning', 'info', 'debug'. Messages with unknown tags are silently dropped. No-op when debug_logging_enabled() is false.

Parameters
$log : mixed

The message or data to log (arrays/objects are JSON-encoded).

$tag : string = "system"

The tag to categorize the log entry. Default "system".

$filter : mixed = null

Optional URI substring filter; skips logging when the current REQUEST_URI does not contain this string.

$invert_filter : bool = false

Whether to invert the filter logic. Default false.

get_config()

Read a site configuration value by key.

get_config(string $key) : mixed

Decodes the global $__site_config JSON string and returns the value for $key, or null when the key is absent or the config is not valid JSON.

Parameters
$key : string

get_current_render_time()

Get the current render time since request received and started processing.

get_current_render_time() : float

This function calculates and returns the current render time.

Return values
float

The current render time in seconds.

indent()

Indent the given text with the given number of spaces.

indent(string $string[, int $indend = 4 ]) : string
Parameters
$string : string
$indend : int = 4

Number of lines to indent

Return values
string

purify_array()

Convert an iterator or object into an array via JSON round-trip.

purify_array(mixed $obj) : array<int|string, mixed>
Parameters
$obj : mixed
Return values
array<int|string, mixed>

uniqidReal()

Generates a unique identifier of a specified length.

uniqidReal([int $length = 13 ]) : string
Parameters
$length : int = 13

The length of the unique identifier to generate. Default is 13.

Return values
string

The generated unique identifier.

access_log()

Write an access log line for the current request.

access_log([int $status = 200 ][, int $length = 0 ][, float|null $durationSec = null ]) : void

Delegates to App::formatAccessLogLine() so the entry honours App::$access_log_format (Apache LogFormat / CustomLog parity) and the trusted-proxy X-Forwarded-For walk in App::clientIp(). No-op when access_logging_enabled() is false.

Parameters
$status : int = 200

The HTTP status code to log.

$length : int = 0

The response body length in bytes.

$durationSec : float|null = null

Request duration in seconds, or null to omit.

response_add_header()

Add a header to the current response.

response_add_header(string $key, string $value[, bool $replace = true ]) : void

Delegates to $g->zealphp_response->header(). The 3rd argument is the $replace flag (PHP header() semantics): true (default) drops prior same-name entries so this value wins; false is the APPEND form, keeping earlier same-name headers so multiple Link / WWW-Authenticate / CSP headers all reach the wire (#260).

Note: the parameter was historically named $ucwords and passed as a DEAD 3rd argument to a 2-param method (silently ignored). It is repurposed here as $replace — every existing 2-arg call keeps the replace-by-default behaviour it already had on the wire, so this is BC.

Parameters
$key : string

The header name.

$value : string

The header value.

$replace : bool = true

Whether to replace a prior same-name header (default true). Pass false to append.

response_set_status()

Sets the HTTP response status code.

response_set_status(int $status) : void

Coerces out-of-range codes to 500 (Apache parity, RFC 7230 §3.1.2 — a status code is three digits, 100-599). This is the single chokepoint every status sink converges on — http_response_code(), header("HTTP/1.1 600 …") and the Status: CGI form all route here — so an out-of-range code never reaches the wire as a silent 200 (OpenSwoole's one-arg status() drops unknown codes). The coercion is logged once here via App::coerceStatusCode() (#292).

Parameters
$status : int

The HTTP status code to set for the response.

response_headers_list()

Retrieves all the response headers.

response_headers_list() : array<int, array{0: string, 1: string}>
Return values
array<int, array{0: string, 1: string}>

An associative array of all the response headers.

setcookie()

Set a response cookie (uopz override of PHP's built-in setcookie()).

setcookie(string $name[, string $value = "" ][, int|array{expires?: int, path?: string, domain?: string, secure?: bool, httponly?: bool, samesite?: string} $expire_or_options = 0 ][, string $path = "" ][, string $domain = "" ][, bool $secure = false ][, bool $httponly = false ][, string $samesite = '' ]) : bool

Validates the cookie name and value for control characters (matching PHP native behaviour since PHP 7). Supports the PHP 7.3+ options-array form for $expire_or_options. Delegates to $g->zealphp_response->cookie().

Parameters
$name : string
$value : string = ""
$expire_or_options : int|array{expires?: int, path?: string, domain?: string, secure?: bool, httponly?: bool, samesite?: string} = 0
$path : string = ""
$domain : string = ""
$secure : bool = false
$httponly : bool = false
$samesite : string = ''
Return values
bool

setrawcookie()

Set a raw (URL-encoded) response cookie (uopz override of PHP's built-in setrawcookie()).

setrawcookie(string $name[, string $value = "" ][, int|array{expires?: int, path?: string, domain?: string, secure?: bool, httponly?: bool} $expire_or_options = 0 ][, string $path = "" ][, string $domain = "" ][, bool $secure = false ][, bool $httponly = false ]) : bool

Like setcookie() but the value is sent as-is without URL-encoding. Supports the PHP 7.3+ options-array form for $expire_or_options. Because the raw variant does NOT url-encode, PHP 8.4 rejects a name or value carrying any of ,; \t\r\n\013\014\0 by throwing a ValueError (not a warning) — this override mirrors that so legacy code relying on the throw behaves identically (#291). setcookie() keeps its warn-and-return-false behaviour because it url-encodes the value, so the same characters are harmless there.

Parameters
$name : string
$value : string = ""
$expire_or_options : int|array{expires?: int, path?: string, domain?: string, secure?: bool, httponly?: bool} = 0
$path : string = ""
$domain : string = ""
$secure : bool = false
$httponly : bool = false
Return values
bool

header()

Set a response header (uopz override of PHP's built-in header()).

header(string $header[, bool $replace = true ][, int|null $http_response_code = null ]) : false|void

Guards against CRLF/NUL injection (HTTP response splitting). Recognises the Apache mod_php status-line forms:

  • header("HTTP/1.1 404 Not Found") — sets the response status code.
  • header("Status: 404 Not Found") — CGI variant; sets the status code.

When $replace is true, any previously queued header with the same name (case-insensitive) is removed before the new value is added.

Parameters
$header : string
$replace : bool = true
$http_response_code : int|null = null
Return values
false|void

http_response_code()

Get or set the HTTP response status code (uopz override of PHP's built-in http_response_code()).

http_response_code([int|null $code = null ]) : int|null

When $code is null, returns the current status. Otherwise sets it and returns null.

Parameters
$code : int|null = null
Return values
int|null

zeal_putenv()

Per-coroutine putenv() — stores the assignment in the request-scoped RequestContext ($g->memo['_env']), which is isolated per coroutine in Mode 4, instead of the process-wide environment. Pairs with getenv().

zeal_putenv(string $assignment) : bool

The process environment stays at its boot value, so concurrent requests no longer race putenv() (a process-level landmine in any persistent server).

Trade-off: subprocesses (proc_open) do NOT inherit a request-scoped putenv — use it for request-scoped config (tenant id, locale), not for child-process environment. Registered only in coroutine-isolated mode (Mode 4).

Parameters
$assignment : string

"NAME=value" to set, or "NAME" to unset.

Return values
bool

zeal_getenv()

Per-coroutine getenv() — reads the request-scoped env first (set via putenv()), then the process environment captured at boot (App::$boot_env). No-arg form returns the merged map. $local_only returns only request-scoped variables (matches the native signature).

zeal_getenv([string|null $name = null ][, bool $local_only = false ]) : string|array<string, string>|false
Parameters
$name : string|null = null
$local_only : bool = false
Return values
string|array<string, string>|false

zeal_shell_exec()

Coroutine-safe shell_exec() shim — routes through App::exec().

zeal_shell_exec(string $cmd) : string|null

Registered as a uopz override of the shell_exec builtin when exec hooking is enabled (see App::$hook_exec). Because the PHP backtick operator compiles down to a shell_exec() call, overriding shell_exec also makes `cmd` coroutine-safe transparently.

Preserves the builtin's documented return shape: null when the command produced no output and failed, otherwise the captured stdout string.

Parameters
$cmd : string
Return values
string|null

zeal_system()

Coroutine-safe system() shim — routes through App::exec().

zeal_system(string $cmd[, int|null &$code = null ]) : string

Echoes the full output (like the builtin) and returns the last line of output, writing the exit code into $code by reference.

Parameters
$cmd : string
$code : int|null = null

Exit status, written by reference.

Tags
param-out

int $code

Return values
string

zeal_passthru()

Coroutine-safe passthru() shim — routes through App::exec().

zeal_passthru(string $cmd[, int|null &$code = null ]) : void

Echoes the raw output and writes the exit code into $code by reference.

Parameters
$cmd : string
$code : int|null = null

Exit status, written by reference.

Tags
param-out

int $code

zeal_exec()

Coroutine-safe exec() shim — routes through App::exec().

zeal_exec(string $cmd[, array<int, string> &$output = [] ][, int|null &$code = null ]) : string

Appends each output line to $output (like the builtin) and writes the exit code into $code by reference. Returns the last line of output.

Parameters
$cmd : string
$output : array<int, string> = []

Output lines, appended by reference.

$code : int|null = null

Exit status, written by reference.

Tags
param-out

int $code

Return values
string

headers_list()

Return all outbound response headers as formatted strings (uopz override of headers_list()).

headers_list() : array<int, string>

Each element is formatted as "Name: value".

Return values
array<int, string>

headers_sent()

Check whether response headers have already been sent (uopz override of headers_sent()).

headers_sent([string|null &$file = null ][, int|null &$line = null ]) : bool

Under OpenSwoole, headers are considered "sent" when the underlying openswoole_response is no longer writable. The $file and $line out-parameters are not populated (no PHP output-started tracking in this runtime).

Parameters
$file : string|null = null

Optional. If provided, this will be set to the filename where output started.

$line : int|null = null

Optional. If provided, this will be set to the line number where output started.

Return values
bool

Returns true if headers have already been sent, false otherwise.

header_remove()

Remove a previously set response header (uopz override of header_remove()).

header_remove([string|null $name = null ]) : void

With no argument (or null), clears all queued response headers. Otherwise removes all headers matching $name (case-insensitive).

Parameters
$name : string|null = null

flush()

Force the current output buffer to the client (uopz override of flush()).

flush() : void

In main-worker mode, this switches the response into streaming mode: headers are flushed once, then body chunks are written via openswoole_response->write(). Subsequent echo + flush() calls stream incrementally. No-op when the response is no longer writable or no response context is available.

ob_flush()

Override of ob_flush() — floor-aware.

ob_flush() : void

Native ob_flush() passes the current buffer's content to the PARENT buffer without closing it. App-level buffers nested ABOVE the framework's capture buffer ($g->_ob_floor, recorded by App::executeFile()) must keep that native semantic; only at the framework floor does "flush" mean "stream to the client".

ob_end_flush()

Override of ob_end_flush() — floor-aware.

ob_end_flush() : void

Native ob_end_flush() pops the current buffer INTO ITS PARENT. The old shim unconditionally streamed-or-DISCARDED, which ate the entire page of any app that ends its bootstrap with a plain nested ob_end_flush() (CodeIgniter 4's Boot::bootWeb() → 200 with a 0-byte body). Above the framework's capture floor we now keep native semantics; at the floor we keep the historical streaming behaviour (flush() + close the re-opened buffer) so legacy "flush everything to the client" callers still work.

ob_implicit_flush()

Apache mod_php ob_implicit_flush() compatibility shim.

ob_implicit_flush([bool|int $enable = true ]) : void

Toggles implicit flush on/off under mod_php. ZealPHP buffers per request by default; this call is accepted as a no-op rather than crashing legacy code.

Parameters
$enable : bool|int = true

phpinfo()

mod_php-parity phpinfo(): render a self-contained HTML document instead of the CLI SAPI's plain-text dump. Matches the native signature — echoes output and returns true. Wired via uopz in App::__construct(); the renderer lives in \ZealPHP\Diagnostics\PhpInfo.

phpinfo([int $flags = INFO_ALL ]) : bool
Parameters
$flags : int = INFO_ALL

INFO_* bitmask.

Return values
bool

php_sapi_name()

mod_php-parity php_sapi_name(): under the CLI SAPI this natively returns "cli", which legacy apps branch on to disable web-only behavior. When an app opts in via App::sapiName('apache2handler') (or 'fpm-fcgi'), this returns the configured value so such code takes its web path. Default (App::$sapi_name === null) returns the real PHP_SAPI — zero behavior change unless explicitly configured.

php_sapi_name() : string

Note: the PHP_SAPI constant cannot be redefined (uopz_redefine refuses it), so code reading the constant directly still sees "cli". Documented limitation.

Return values
string

filter_input()

mod_php-parity filter_input(): native filter_input() reads PHP's internal SAPI request tables, which OpenSwoole never populates (so it returns null under CLI).

filter_input(int $type, string $var_name[, int $filter = FILTER_DEFAULT ][, array<string, mixed>|int $options = 0 ]) : mixed

This resolves the value from RequestContext ($g) and applies the requested filter.

Parameters
$type : int
$var_name : string
$filter : int = FILTER_DEFAULT
$options : array<string, mixed>|int = 0

filter_input_array()

mod_php-parity filter_input_array(): the array counterpart of filter_input().

filter_input_array(int $type[, array<string, mixed>|int $options = FILTER_DEFAULT ][, bool $add_empty = true ]) : array<string, mixed>
Parameters
$type : int
$options : array<string, mixed>|int = FILTER_DEFAULT
$add_empty : bool = true
Return values
array<string, mixed>

header_register_callback()

mod_php-parity header_register_callback(): native PHP fires the callback when the SAPI is about to send headers — which never happens the normal way under OpenSwoole. ZealPHP stores it per-request (coroutine-safe, in $g->memo) and invokes it once just before the buffered response headers are flushed, so header() calls inside the callback still land. Last registration wins (matches native, which keeps a single callback). Returns false if there's no request context (e.g. called outside a request).

header_register_callback(callable $callback) : bool

Scope note: fires for buffered responses (the common case). Streaming / SSE paths flush headers eagerly and are intentionally excluded, consistent with the framework's buffered-vs-streaming split (e.g. Range/ETag middleware).

Parameters
$callback : callable
Return values
bool

error_log()

mod_php-parity error_log(): under the CLI SAPI native error_log() writes to stderr / the php.ini error_log path. ZealPHP routes message_type 0 (system logger) and 4 (SAPI logger) into the framework's async log (debug.log, or stderr if logging is disabled) so legacy error_log() calls land where the rest of the app's diagnostics go — the "we have elog for error_log" contract.

error_log(string $message[, int $message_type = 0 ][, string|null $destination = null ][, string|null $additional_headers = null ]) : bool
  • type 3 (append to file): honored verbatim — explicit destination intent.
    • type 1 (email): unsupported under the coroutine runtime; logged + false.
    • type 0 / 4: routed to log_write() (debug.log → stderr fallback).

Always lands somewhere (never silently dropped), unlike elog() which gates on debug logging; that's why this routes through log_write() directly.

Parameters
$message : string
$message_type : int = 0
$destination : string|null = null
$additional_headers : string|null = null
Return values
bool

apache_request_headers()

Apache mod_php getallheaders() / apache_request_headers() — return all inbound request headers with canonical (Hyphen-Capitalized) case.

apache_request_headers() : array<string, string>
Return values
array<string, string>

getallheaders()

Alias for apache_request_headers() — return all inbound request headers.

getallheaders() : array<string, string>
Return values
array<string, string>

apache_response_headers()

Apache mod_php apache_response_headers() — return currently queued outbound headers.

apache_response_headers() : array<string, string>
Return values
array<string, string>

apache_setenv()

Apache mod_php per-request env table setter (apache_setenv()).

apache_setenv(string $variable, string $value[, bool $walk_to_top = false ]) : bool

Backed by Legacy\ApacheContext on G; lifetime = one request. Lazy — only allocated if legacy code calls apache_setenv()/apache_getenv()/apache_note(). The $walk_to_top flag is accepted for API compatibility but has no effect.

Parameters
$variable : string
$value : string
$walk_to_top : bool = false
Return values
bool

apache_getenv()

Apache mod_php per-request env table getter (apache_getenv()).

apache_getenv(string $variable[, bool $walk_to_top = false ]) : string|false

Returns false when no Apache context has been initialised or the variable is not set. The $walk_to_top flag is accepted for API compatibility but has no effect.

Parameters
$variable : string
$walk_to_top : bool = false
Return values
string|false

apache_note()

Apache mod_php apache_note() — per-request note table. Returns previous value.

apache_note(string $note_name[, string|null $note_value = null ]) : string

When $note_value is null, acts as a getter only. Setting a value lazily initialises the ApacheContext if needed.

Parameters
$note_name : string
$note_value : string|null = null
Return values
string

virtual()

Apache mod_php virtual() — performs an internal subrequest.

virtual(string $uri) : bool

Not supported in ZealPHP's single-process model; logs once via elog() and returns false rather than crashing legacy code.

Parameters
$uri : string
Return values
bool

set_time_limit()

set_time_limit() compatibility shim.

set_time_limit(int $seconds) : bool

OpenSwoole has its own coroutine/worker timeouts and the native PHP execution-time limit is irrelevant here. Treated as no-op success.

Parameters
$seconds : int
Return values
bool

ignore_user_abort()

ignore_user_abort() compatibility shim (uopz override).

ignore_user_abort([bool|null $enable = null ]) : int

Apache mod_php controls whether the script keeps running after the client disconnects. The state is tracked in G; with OpenSwoole the coroutine continues regardless, but we honor the API contract. When called with no argument, returns the current setting without changing it.

Parameters
$enable : bool|null = null
Return values
int

connection_status()

Return the connection status for the current request.

connection_status() : int

Returns 1 (CONNECTION_ABORTED) when the underlying openswoole_response is no longer writable, 0 (CONNECTION_NORMAL) otherwise.

Return values
int

connection_aborted()

Return 1 when the client connection has been aborted, 0 otherwise.

connection_aborted() : int

Equivalent to connection_status() === 1.

Return values
int

output_add_rewrite_var()

Apache's URL-rewrite output handler — not used in ZealPHP. No-op returning false.

output_add_rewrite_var(string $name, string $value) : bool
Parameters
$name : string
$value : string
Return values
bool

output_reset_rewrite_vars()

Apache's URL-rewrite output handler reset — not used in ZealPHP. No-op returning true.

output_reset_rewrite_vars() : bool
Return values
bool

is_uploaded_file()

is_uploaded_file() compatibility shim (uopz override).

is_uploaded_file(string|null $filename) : bool

Verifies that $filename is one of the temp paths registered in this request's $_FILES (via $g->files). Rejects forged paths from user input.

Parameters
$filename : string|null
Return values
bool

_zealphp_tmp_name_matches()

Recursively test whether $filename is one of the temp-path leaves in a field-major $_FILES[...]['tmp_name'] value (scalar or nested array).

_zealphp_tmp_name_matches(mixed $tmp, string $filename) : bool
Parameters
$tmp : mixed

Scalar tmp path or an (possibly nested) array of them.

$filename : string
Return values
bool

move_uploaded_file()

move_uploaded_file() compatibility shim (uopz override).

move_uploaded_file(string|null $from, string|null $to) : bool

Equivalent to Apache+mod_php behaviour, gated by is_uploaded_file() and falling back to copy()+unlink() across filesystems when rename() fails.

Parameters
$from : string|null
$to : string|null
Return values
bool

set_error_handler()

Per-request set_error_handler() (uopz override).

set_error_handler(callable|null $callback[, int $error_levels = E_ALL ]) : callable|null

The native PHP error handler is installed at boot and delegates to G's per-coroutine stack. This override records the user-space registration in $g->error_handlers_stack without touching the engine handler. Passing null pops the most recently registered handler (matches native behaviour).

Parameters
$callback : callable|null
$error_levels : int = E_ALL
Return values
callable|null

restore_error_handler()

Pop the most recently registered per-request error handler.

restore_error_handler() : bool

Mirrors the native restore_error_handler() contract; always returns true.

Return values
bool

set_exception_handler()

Per-request set_exception_handler() (uopz override).

set_exception_handler(callable|null $callback) : callable|null

Stores the handler in $g->exception_handlers_stack. Passing null pops the most recently registered handler. Returns the previously active handler (or null when none was set).

Parameters
$callback : callable|null
Return values
callable|null

restore_exception_handler()

Pop the most recently registered per-request exception handler.

restore_exception_handler() : bool

Mirrors the native restore_exception_handler() contract; always returns true.

Return values
bool

register_shutdown_function()

Per-request shutdown function (uopz override of register_shutdown_function()).

register_shutdown_function(callable $callback, mixed ...$args) : void

Fires after the route handler returns and before the PSR response is emitted, so the callback can still call echo/header()/http_response_code() and have those land in the response. Multiple callbacks are supported and called in registration order.

Parameters
$callback : callable
$args : mixed

error_reporting()

Per-coroutine error_reporting() (uopz override).

error_reporting([int|null $error_level = null ]) : int

When called without an argument, returns the current reporting level for this coroutine (falling back to the level captured at App boot via App::$initial_error_reporting). When called with a level, stores it in $g->error_reporting_level and returns the previous level.

Parameters
$error_level : int|null = null
Return values
int
On this page