Tags give the ability to mark specific points in history as being important
-
v0.4.15
f29817e7 · ·Release v0.4.15 - feat(#494): RedisSessionHandler AUTH support. New optional trailing $auth — a requirepass password, or [user, pass] for a Redis 6+ ACL user — sent via AUTH on each new connection, and ONLY when configured (Redis errors on an AUTH to a passwordless server, so an unconditional call would break every existing no-password deployment). Trailing + defaulted, so 4-argument call sites are untouched. Until now any deployment using this handler was forced to run its session store with no requirepass: enabling one failed every session read/write with NOAUTH and logged out every user. - Connection surface relaxed private -> protected ($host/$port/$prefix/$ttl/ $auth/$fallback + connect()/conn()) so TLS options, custom timeouts or a non-zero DB select() can be added by subclassing rather than reimplementing SessionHandlerInterface and duplicating the coroutine 3-way merge. Verified end-to-end on Valkey 8.1.9 and Redis 6.0.16 (6/6 checks each), including that a no-password handler is REJECTED by the authed server, that [user, pass] authenticates as a scoped ACL account, and that null auth still works against a passwordless server. ext-zealphp pin unchanged (v0.3.60).
-
v0.4.14
5f8a10e4 · ·Release v0.4.14 - fix(#490): the Tiered 'cross-node L1 invalidation is OFF' advisory was decided at defaultBackend() build time, but enableInvalidation() needs a coroutine and is only legal from an App::onWorkerStart() hook — so the warning was structurally unsatisfiable, and its always-winning branch MASKED the security advisory (invalidation ON but UNAUTHENTICATED: any Redis writer can forge an L1-evict and DoS the cluster's caches). Decision now deferred past the worker-start hook chain, worker-0 gated, idempotent, evaluated against the current backend. 7 new tests pin the timing contract. - docs(#489): error_log() is overridden to write into debug.log, not stderr — previously undocumented, and invisible in containers. Documented with a four-way probe table plus a container-friendly logging recipe (php://stdout / php://stderr). - docs(#491): App::onWorkerStart() is called as $fn($server, $workerId); the one-arg example bound the Server to $workerId, silently breaking the 'worker 0 only' idiom. Example fixed + explicit signature section added. ext-zealphp pin unchanged (v0.3.60).
-
v0.4.13
ce3d7901 · ·Release v0.4.13 - App::sharedStatics() — worker-global statics opt-out for coroutine-legacy throughput; every other legacy semantic stays per-request (#483) - fix(#485): file-based api/ endpoints reachable at ANY nesting depth — processApi() folds deep tail dirs into $module; adversarially test-pinned - ext-zealphp pin v0.3.59 -> v0.3.60: ext#59 per-coroutine constant lanes (cross-coroutine define() leak 97%->0, corrupted-zval OOM eliminated) + coroutine-legacy request-begin statics perf fix (/ping 3,678 -> 15,657 rps, within 0-20% of plain coroutine) - bug wave #467/#471/#474 + #478 urlencoded-POST raw-body fallback - release-audit test-gap fill: PoolWorkerVarIsolationTest (#467), ext phpt 072 (begin-exemption)
-
v0.4.12
2361ad50 · ·Release v0.4.12 - echo/print interleave with yield in streamed generators (wire-order flush). - ext#55 async-log consumer coroutine leak under coroutine-legacy (ext 0.3.59). - #443 fork-CGI child streams returned Generator/Closure. - #453 getallheaders()/apache_request_headers() in CGI subprocess. - #449 ZEALPHP_MAX_REQUEST=0 disables worker recycle. #442 render() template-dir confinement. - #459 SERVER_NAME host-only. #455 null-upload parity. #448 get_string_between. - #444/#446 htmx separate-template + nested-fragment. #458/#454/#457 page-scope isolation. - docs: PSR table (#451), 4 isolation/exit env knobs (#450), api verb-named gotcha. - chore: docker PHP 8.5; CI/dev dep bumps.
-
v0.4.11
1c12cd69 · ·ZealPHP v0.4.11 - WordPress $wp_object_cache lost-global under coroutine-legacy concurrency FIXED (consumed via ext-zealphp 0.3.57): wp_start_object_cache() `static $first_init` leaked across coroutines → switch_to_blog()-on-null. Request-begin function-static refresh + in-place end-reset. WP c8x200=200/200, c16x480=480/480, RSS flat. - With the $wpdb-null Phase R fix (v0.4.10 / ext 0.3.56), unmodified WordPress now serves clean under coroutine-legacy concurrency. - New App::runRequestStaticsBeginRefresh() helper (unit-tested); session managers call it under the perRequestStateResetsActive() gate.
-
v0.4.10
8e8d13d9 · ·ZealPHP v0.4.10 - $wpdb-null functional concurrency race RESOLVED (consumed via ext-zealphp 0.3.56 Phase R): deep-frame global CV convergence; WP prepare()-on-null 160->0. - #438: RedisSessionHandler per-coroutine \Redis FD leak fixed via Coroutine::defer close (no more maxclients exhaustion). - Patched-opcache coroutine-legacy recipe complete (ZEALPHP_PATCH_OPCACHE: enable_cli + dups_fix + validate_timestamps=0) — unmodified WordPress leak-free under coroutine-legacy. - USE_ZEND_ALLOC=0 reframed as a non-fix (canonical doc); production fix is max_request recycle. - Guru issue wave (#432 + siblings, #435) folded in.
-
v0.4.9
fecab712 · ·Release v0.4.9 The cold-concurrent worker-corruption class is closed (ext pin v0.3.52, S5b v2 per-coroutine object-static isolation — ext#44/#48/#49). Rolls the large cluster since 0.4.0: session security + correctness, exit/die HaltException, #379 session persistence, the output-buffer 0-byte-body fix, ZealAPI scope + mode-aware null, the isolation-stage taxonomy, and the just-works roadmap. Also: uniform $app->App-instance injection, per-verb route helpers, README stars-badge fix, Cache stampede-lock test-isolation fix.
-
v0.4.8
f3232503 · ·Release v0.4.8 - RequestContext::__isset()/__unset() — truthful isset() on unset-and-proxied superglobal slots (coroutine-legacy populate, #346 Apache bridge). Closes the ext-zealphp#42 residual: $g->server['X'] ?? fallback no longer silently takes the fallback, and app-side defensive guards (if (!isset($g->server)) $g->server = [];) can no longer wipe the live $_SERVER through __set. Root-caused + verified live on the labs parity rig — full original #42 route table green, LEGACY byte-equivalent to COROUTINE mode. - __unset stays a no-op for proxied names so framework slot-detach can never escalate into superglobal deletion (a re-bridge nuked $_ENV pre-guard). - CHANGELOG hygiene: stray [Unreleased] entries re-homed (locale/umask -> 0.4.6, TableSessionHandler -> 0.4.5), preamble deduped.
-
v0.4.7
f034da4c · ·Release v0.4.7 — coroutine-legacy correctness batch ext-zealphp pin -> v0.3.46. - App::go() + automatic request-context inheritance for child coroutines (ext#42) - Fatal->500 guard: a worker-killing fatal answers in-flight connections with HTTP 500 instead of HTTP 000 (#338) - coroutine-legacy correctness batch via ext 0.3.41-0.3.46: per-request-state claim-set gate (ext#37), $_SERVER post-yield integrity (ext#40/#41), child superglobal lane (ext#42), define() constant-leak fix (0.3.44), per-coroutine tz/mb/libxml isolation (0.3.45), mysqlnd vio orig_path allocator shim that eliminates the WordPress teardown zend_mm_heap corruption (ext#44) - Cold-autoload duplicate-CE crash fixed via master-side request-path preload - Include-boundary $g mutation loss (ext#43), Apache $g superglobal bridge (#346), ZealAPI null->404 parity (#347)
-
v0.4.6
d064c12f · ·Release v0.4.6 - Package renamed: sibidharan/zealphp → zealphp/zealphp (Packagist vendor namespace). GitHub repo unchanged. composer.json 'replace' keeps sibidharan/zealphp resolvable in mixed graphs; the old Packagist package serves all existing tags forever (abandoned with replacement pointer). Install commands now read 'composer create-project zealphp/project' and 'pie install zealphp/ext'.
-
v0.4.5
7b1d6cfc · ·Release v0.4.5 - Session-correctness sweep: regenerate-id sid desync (broke session_regenerate_id(true) login flows in every mode), strict-mode rotation of issued-but-empty sessions, and superglobal OWNERSHIP gating with ext-zealphp 0.3.36/0.3.37 — the go()-child steal (first-request 501s, #332) and the service-coroutine restore wipe (ext#32). Session counters deterministic across bare Mode 4 + coroutine-legacy on PHP 8.3 + 8.4. - Security: WS rooms/routing follow session auth (#234), ScopedMiddleware path-normalization bypass (#232), IpAccessMiddleware trusted proxies (#239). - mod_php parity: REQUEST_URI query string (#306), $_COOKIE treat-data (#305), $_FILES field-major (#304), Basic-auth $_SERVER (#307), Set-Cookie byte-parity + SameSite=None warning (#293/#319), raw status-line passthrough (#327), filter_input in CGI workers (#316). - Pool cold-start TOCTOU connection leak (#322), sendFile delegates to ConditionalRequest + MimeResolver (#321/#317), per-coroutine CWD isolation (#323, ext 0.3.35), quick-wins #308-#311/#318/#320, fcgi hang (#289), session handlers in coroutine mode (#295). - ext-zealphp default pin -> v0.3.37.
-
v0.4.4
4e4071f9 · ·Release v0.4.4 — RedisSessionHandler coroutine-safety (#285) Fixed: - #285 (follow-up to #271): RedisSessionHandler open/read/write/destroy no longer fatal 'API must be called in the coroutine' when the session save-handler chain fires outside a request coroutine under superglobals(true) + HOOK_ALL without enableCoroutine(true). Each Redis op now runs inside Coroutine::run() when outside a coroutine (reusing the persistent fallback so WATCH/MULTI/EXEC spans read->write); per-coroutine path (issue #16) unchanged. Validated on PHP 8.4 + OpenSwoole 26.2.0 + phpredis 6.3. No ext-zealphp change (stays v0.3.33).
-
v0.4.3
6fa77033 · ·Release v0.4.3 — migration-hardening Security: - #240 reserved framework-object params bind before same-named URL segments Fixed: - #260 CGI workers preserve multiple same-name response headers - #261 cgiMode('fcgi') no longer fatals every request (coroutine-wrapped FastCGI) - #270/#274 $g->server CGI/SAPI vars at worker start + per-request UNIQUE_ID - #271 RedisSessionHandler connects lazily (no HOOK_ALL fatal in onWorkerStart) - #26 boot-time $GLOBALS visible to all request coroutines (needs ext-zealphp 0.3.33+) Plus the architecture-review hardening pass (backpressure, sessions, cross-node fabric). Companion: ext-zealphp v0.3.33. -
v0.4.2
fc2b145a · ·Release v0.4.2 — security + correctness audit fixes + ext-zealphp 0.3.32 - Security: open-redirect block-by-default (#243), clientIp() XFF-spoof fix (#249), CIDR fail-closed (#248), access-log CRLF escaping (#250), CGI pool env / httpoxy (#257), session-fixation strict-mode (#244), Memcached object-injection (#251) - Fixed: Store/Counter backends (#241 #242 #252 #254 #255 #256), HTTP/WS (#246 #247 #253 #258 #259 #260), #227 reset-gate corruption - ext-zealphp 0.3.32: IS_INDIRECT $GLOBALS isolation, superglobal session-leak reset, constant + class-static UAF, include-isolation + require_global (#8-#18), ASAN+Valgrind - Docs: coroutine-isolation security-research guide - Two behaviour changes (redirect, clientIp), both security-motivated
-
v0.4.1
eba0b20f · ·Release v0.4.1 — REST::response() default, CLI dashed subcommands, template IDE docs, llms.txt refresh
-
v0.4.0
597df233 · ·Release v0.4.0 First-class HTMX support: - App::renderHtmx() — htmx-aware fragment / full-page rendering (HX-Target derived) - HtmxResponse::triggerJSON() + chain-back response() - Consolidated HTMX guide (docs/htmx.md + /htmx page), already had full HX-* header coverage Also: - $req / $res handler-parameter aliases (route / api / fallback / template closures) - Env config for the whole CGI subprocess pool (ZEALPHP_CGI_WORKERS + 4 more) - Foreground start banner for a plain 'php app.php' - Redesigned scaffold: Terminal-Luxury theme + live htmx playground
-
v0.3.9
84f0ee36 · ·Release v0.3.9 Scale + hardening release (re-cut from the mis-numbered v0.4.0 — same content, corrected version per the project's patch cadence). Features: DbConnectionPool (PDO + mysqli) · Store::eval() + per-room server-set (cross-node fan-out B1) · Stage 8 App::globalScopeInclude() (experimental). Scale fix: sharded TableSessionHandler write lock. Hardening: session / cache / store-counter / WebSocket / pub-sub-middleware / RedisStreams / in-memory-session audit batches. BC: HaltException extends \Error (#194); Counter::raw() returns Atomic\Long (64-bit).
-
v0.3.8
f9594ccf · ·Release v0.3.8 - App::cgiMode('fork') — Apache MPM-prefork-style CGI runner (fresh child per request, true global scope, no 'Cannot redeclare'). - Per-route CGI backend — the backend: route option + App::cgiBackendAlias(). - Patched-opcache Docker build (ZEALPHP_PATCH_OPCACHE) keeping opcache fully on in coroutine-legacy for require_once apps (php-src#22214 function-dups fix). - WordPress media uploads + wp-admin/Gutenberg in the cgi-pool/cgi-proc modes. -
v0.3.7
0ffdff93 · ·Release v0.3.7 - src/App.php broken down 9690→~7600 lines: ResponseMiddleware, CLI, CGI\Dispatcher, Middleware\Pipeline\*, LocationHeaderMiddleware, TemplateUnavailableException extracted (run() decomposed into registerOnRequest/WorkerStart/WorkerStop — zero logic change) - route() ergonomics: handler accepted as the last positional arg (no handler: keyword) - Per-route + App::when() path-scoped middleware, in-file $middleware for api files - Dev route hot-reload (--dev / ZEALPHP_DEV=1 / App::devReload) + CLI docs - phpinfo redesign: Apache-parity system/extension/environment sections + sticky TOC - Per-user log-dir fallback (resolve_log_dir) when /tmp/zealphp is root-owned - ext-zealphp pinned to v0.3.25 across setup.sh + Dockerfile - Fixes: #164 (RequestContext array superglobal __get), #157 (root-level api 404), #155 (registerCgiBackend exec_paths validation)
-
v0.3.6
b08f0830 · ·Release v0.3.6 — coroutine-legacy per-request state-reset stack + opcache advisory Completes the PHP-FPM "fresh process per request" contract for the require_once-legacy class. - ext-zealphp 0.3.25: per-request function-static + class-static reset (mirror shutdown_executor); free_zend_constant worker-exit fix. - App::opcacheLegacyBootCheck() advisory for opcache + coroutine-legacy. - Validated PHP 8.4 + ASAN across a 12-app sweep; WordPress serves public + login-auth + comment-write end-to-end. - phpt 38/38, PHPStan L10, phpunit 3225/3225.