Tags give the ability to mark specific points in history as being important
-
v0.2.23
aecc3fc6 · ·Release v0.2.23 - Added: App::processIsolation(?bool), App::enableCoroutine(?bool), App::hookAll(bool|int|null) — fluent setters that decouple the four lifecycle decisions previously bundled inside App::superglobals(). Each defaults to null → resolves to "follow $superglobals" at run() time, so existing apps see no behaviour change. - Enables the "Mixed-mode / Symfony" lifecycle (superglobals=true + processIsolation=false + sessionLifecycle=false): real $_SESSION without the ~30-50 ms CGI fork cost on every App::include() call. - Added: lifecycle mode matrix in CLAUDE.md documenting the six supported combinations and the two unsafe-but-warned combinations. - Changed: App::run() resolves lifecycle decisions through the new setters; emits [lifecycle] warnings to the debug log for combinations that race process-wide $_GET/$_POST/$_SESSION across coroutines. - Changed: internal OpenSwoole\Runtime::enableCoroutine() call switched to canonical two-arg form (PHPStan level 10 cleanliness). PHPStan level 10 clean. 321 unit + 146 integration tests pass.
-
v0.2.22
1f79e1ab · ·Release v0.2.22 - Fix: $_SESSION ↔ $g->session bridge in superglobals mode (RequestContext's typed property was shadowing the __get/__set proxy, breaking session interop with Symfony/Laravel and any framework that writes through $_SESSION). Full sweep across zeal_session_start/write_close/status/ destroy/unset/abort/encode/decode. - Fix: zeal_session_status() no longer false-positives PHP_SESSION_ACTIVE on fresh worker in superglobals mode (was tripping Symfony's NativeSessionStorage "already started by PHP" guard). - Added: App::sessionLifecycle(?bool) opt-out for external frameworks that own the session lifecycle. Eliminates the duplicate PHPSESSID cookie war. Enables Symfony-on-ZealPHP via the zealphp-symfony bridge.
-
v0.2.19
f597ce80 · ·Release v0.2.19 — Tier 1 security/quality CI: composer audit + Dependabot + CodeQL + gitleaks. Plus poser→shields.io badge fix.
-
v0.2.18
1522955e · ·Release v0.2.18 — fix composer.lock out of sync on v0.2.17 (PHPStan 2.1.54 pin)
-
v0.2.17
393b4a92 · ·Release v0.2.17 — PHPStan 2.x level 10, 0 errors. Vendor cleanup, CI hygiene, PHP 8.5 matrix.
-
v0.2.16
e592559d · ·Release v0.2.16 — PHPStan level 6 → 9 (final climb of three-release series). 0 errors at level 9, 74 documented ignore-sites, 6 real bugs fixed.
-
v0.2.15
98306c5b · ·Release v0.2.15 — PHPStan level 5 → 6 (annotation cliff complete; 369 missing-type errors fixed)
-
v0.2.14
2d31827e · ·Release v0.2.14 — PHPStan level 1 → 5 (first of three releases climbing to level 9)
-
v0.2.13
890a4896 · ·Release v0.2.13 Framework - CorsMiddleware: env-var origins (ZEALPHP_CORS_ORIGINS) + one-time warning when defaulting to wildcard '*'. Backward-compatible. - static_handler_locations default fixed — trailing-slash directory entries prevent /js intercepting /json (and similar prefix collisions). Main repo demo / website - app.php cleanup: PSR-12, drop hardcoded TZ + backtick git describe, fix /json session leak, remove /exittest (calls exit() = worker kill) and 9 other junk demo routes. - Demo middleware moved to examples/ with honest names. Triggered by public app.php line-by-line review. Full trace in CRITIC.md.
-
v0.2.12
1becefb4 · ·Release v0.2.12 — session-file corruption worker-crash fix Stability fix (high severity, DoS class): Production-breaking TypeError on corrupted / empty / non-array session payloads. unserialize() false → typed array assignment → worker abnormal exit. Affects all v0.2.6 through v0.2.11. Fixed at three call sites in src/Session/utils.php: - zeal_session_start (request entry) - zeal_session_reset (mid-request reset) - zeal_session_decode (user-controlled input) zeal_session_decode now returns bool matching PHP native signature. 11 new regression tests in SessionFileCorruptionTest.php cover empty / corrupted / garbage / non-array / missing-file scenarios. ROADMAP.md restructured around 'v0.2.x = security & migration' framing. Connection pool moved out of v0.3 into remaining v0.2.x items — it's a production-trust gap, not an observability feature. 204 unit tests, PHPStan green. See CHANGELOG.md and CRITIC.md.
-
v0.2.11
d06845d4 · ·Release v0.2.11 — open-redirect hardening + docs cleanup Security: - Response::redirect() rejects leading/trailing whitespace and backslash. Closes a real open-redirect / stored-XSS bypass of v0.2.5's scheme guard: ' javascript:alert(1)' was getting through because the regex anchor failed to match URLs with leading whitespace, and browsers strip the whitespace before parsing the Location header. - All v0.2.5 through v0.2.10 are affected. Upgrade recommended for any app that passes user input directly to Response::redirect(). - 7 new redirect regression tests. Tests: - 17 new RequestContext invariants tests pinning the v0.2.6 architectural contracts (class_alias identity, strict __set, response state location, ApacheContext lazy alloc, etc.). Docs: - deployment.php env var table rewritten with all 20 ZEALPHP_* vars. - migration / sessions / middleware / README updated for v0.2.6+ rename and v0.2.10 additions. 193 unit tests, PHPStan green. See CHANGELOG.md and CRITIC.md.
-
v0.2.10
54dddee8 · ·Release v0.2.10 — discipline-contract sprint Closes the visibility gap on the per-coroutine isolation contract raised in this week's public technical review: - RequestContext::once(\$key, \$fn) helper (Laravel 11 once() analog) - Worker-recycle access log line - Opt-in IniIsolationMiddleware - Coroutine safety matrix + Store semantics docs - OPcache production tuning notes - Handler stack reset in superglobals mode 169 unit tests, PHPStan green. See CHANGELOG.md and CRITIC.md.
-
v0.2.8
1e28fc3e · ·Release v0.2.8 — PHPStan CI green again After the v0.2.6 G → RequestContext rename, PHPStan flagged 90 "unknown class" errors because it doesn't follow runtime class_alias. This release migrates framework-internal G:: references to the canonical RequestContext:: name across src/. The class_alias for external user-code backward compat is unchanged. PHPStan: 0 errors. Unit tests: 155/155.
-
v0.2.7
65d812f0 · ·Release v0.2.7 — relax setrawcookie filter v0.2.5 introduced CRLF/NUL injection guards on cookie/header sinks. The setrawcookie value filter was too strict — it rejected legal raw cookie-octets (space, comma, semicolon) that PHP native accepts. Now matches PHP behavior: rejects only \r\n\0 in the value. CRLF guards on header(), Response::header(), redirect(), setcookie() are unchanged. Existing testSetRawCookieDoesNotUrlEncode integration test confirms.
-
v0.2.6
93ef26ad · ·Release v0.2.6 — RequestContext rename + structural cleanup Addresses architectural critiques raised by henderkes / olle.haerstedt on the G class structure. Backward-compatible via class_alias. - G renamed to RequestContext (\ZealPHP\G remains via class_alias) - Response state moved from G onto Response ($response->headersList etc.) - Apache shim state moved to ZealPHP\Legacy\ApacheContext (lazy) - #[AllowDynamicProperties] removed; previously-dynamic props declared - Return-by-reference autovivification eliminated in coroutine mode - Dead prefork_request_handler() deleted (CGI bridge supersedes it) - debug_backtrace() in instance() removed - Redundant isset() in CoSessionManager simplified External API for framework-internal arrays changed; uopz overrides (header, setcookie, apache_setenv) are unaffected. All 155 tests pass.
-
v0.2.5
371e3737 · ·Release v0.2.5 — security fix: HTTP response splitting The uopz header() override didn't reject CRLF/NUL in values, breaking PHP's native protection (in place since 4.4.2). User-controlled input passed to header() / setcookie() / redirect() could smuggle additional response headers, enabling session fixation and cache poisoning. All entry points patched: - header(), Response::header() - Response::redirect() - setcookie(), setrawcookie() Cookie name char-class rules now match PHP native setcookie. 9 new regression tests added. All v0.2.x releases prior to v0.2.5 are affected. Upgrade recommended.
-
v0.2.4
41cf90b1 · ·Release v0.2.4 - max_request=100000 default — bounded worker recycling for long-running PHP, with ZEALPHP_MAX_REQUEST env var override. - Scaffold defaults to coroutine mode (App::superglobals(false)) — aligns with the documented "recommended for new projects" stance and sidesteps the worker-state-leak class of issues for greenfield apps. - Framework default (App::$superglobals = true) is unchanged for backward compatibility with existing installs upgrading via composer update.
-
v0.2.3
e6a4e0a3 · ·Release v0.2.3 - SessionStartMiddleware: eager session for first-time visitors - 14-lesson tutorial redesign with pedagogical structure - Lesson 5: React vs PHP (frontend-agnostic positioning) - AI agent calls HTTP API with session cookie auth - Mermaid diagrams with pop-out zoom/pan viewer - Event log terminal, note animations, concept check quizzes - Inline auth error feedback via htmx - Notes API JSON content negotiation
-
v0.2.2
6f838cba · ·Release v0.2.2 - 13-lesson /learn tutorial: Notes + AI Chat app with htmx, SQLite, SSE, WebSocket - src/Learn/ namespace: 6 autoloaded classes (Auth, Chat, Notes, DB, ChatHistory, WS) - 8 ZealAPI endpoint files (api/learn/) - Python OpenAI Agents SDK notes agent with 6 function tools - WebSocket session support in framework (App.php onOpen) - ZealAPI SSE streaming fix (ZealAPI.php _streaming check) - PSR-2 coding standards codified in CLAUDE.md - htmx site-wide (hx-boost), cache-busting asset URLs - 259 tests, 600 assertions
-
v0.2.1
4c002024 · ·Release v0.2.1 — homepage redesign + Apache parity hardening (re-tagged with sitewide ^0.2.1 install refs)