Tags

Tags give the ability to mark specific points in history as being important
  • v0.3.5

    Release v0.3.5 — coroutine-legacy compatibility runtime
    
    - ext-zealphp 0.3.17: per-coroutine isolation of every request-state
      primitive (7 superglobals, $GLOBALS / global $x, function-local static $x,
      define(), ini_set, putenv/getenv, silent function/class redeclare,
      require_once/include_once) via dlsym'd OpenSwoole on_yield/on_resume/
      on_close scheduler hooks. NTS-only.
    - App::mode('coroutine-legacy'|'legacy-cgi'|'coroutine'|'mixed') one-knob
      lifecycle + App::isolation(); six standalone isolation setters.
    - TableSessionHandler + App::sessionHandler/sessionMaxRows/sessionTtl —
      concurrent-safe sessions via 3-way (base/disk/memory) merge.
    - Fix: isolate global-keyword vars per coroutine on PHP 8.4/8.5
      (Stage-2 IS_REFERENCE deref); auto-drop HOOK_FILE under silentRedeclare+
      coroutine; executeFile() chdir; ext security hardening passes 1+2;
      pool worker survives exit()/die() (FD-3 IPC).
    - Known limitation (HAZARD-2): coroutine-legacy CODE isolation on PHP
      8.4/8.5 has a pre-existing heap-corruption race under heavy concurrent
      class autoloading (not a state leak; absent on 8.3). STATE isolation is
      solid on 8.3/8.4/8.5.
  • v0.3.4

    Release v0.3.4
    
    - Disabled zealphp_coroutine_superglobals() — dlsym hooks cause SIGSEGV
    - Session: _session_started flag, CoSessionManager for ec=true, dedup PHPSESSID
    - 10/12 lifecycle modes pass 7/7
  • v0.3.3

    Release v0.3.3
    
    Bug fixes (14 issues closed):
    - #133/#135: Pool worker READY handshake — loop-read stderr, skip warnings
    - #134: Use CoSessionManager when coroutines enabled (SessionManager races)
    - #136: Duplicate PHPSESSID — _session_started flag + static save handler guard
    - #137: Reject sg(false)+ec(false) at boot (CoSessionManager needs scheduler)
    - #143: ZEALPHP_CGI_MODE=pool no longer parsed as proc
    - #142: python3 CGI backend conditional (skip when not installed)
    - #141: uopz skip guards for ext-zealphp-only environments
    - #140: CI builds ext-zealphp from pinned submodule
    - #138: Isolation scope documented (superglobals only, not $GLOBALS)
    - #132: Copy button works on all pages (moved to global JS)
    - #130: exec_paths docblock added to registerCgiBackend()
    - #139: Mode 6 co-state fixture — closed as expected behavior
    - Reverted premature auto-enable coroutines for sg(true)
    - Removed auto-wired zealphp_define_hook/constants_clear
    
    ext-zealphp v0.3.1:
    - define() isolation, $GLOBALS isolation, process-state snapshot/clean
    - Zombie class fix for static property cleanup
  • v0.3.1

    Release v0.3.1 — setcookie array, die() fix, session_destroy, lesson 3
  • v0.3.0

    Release v0.3.0 — ext-zealphp replaces uopz
    
    ext-zealphp: ZealPHP's own ~650-line C extension
    - 8 PHP functions: override/restore + superglobals management + coroutine hooks
    - 53 PHP built-in function overrides (allowlist-only, no class manipulation)
    - Per-coroutine superglobal isolation via OpenSwoole scheduler hooks
    - 16 PHPT tests, proven zero-leak with Channel-synchronized interleaving
    - PIE-ready: pie install sibidharan/ext-zealphp
    
    Framework:
    - App.php auto-detects ext-zealphp > uopz fallback
    - superglobals(true) + enableCoroutine(true) now SAFE with ext-zealphp
    - composer.json: ext-uopz removed from require
    - setup.sh: all 3 paths (Linux/Docker/macOS) install ext-zealphp
    - CI: builds ext-zealphp from source in test pipeline
    
    Docs: uopz → ext-zealphp across 20+ pages, PECL → PIE,
    5 new mermaid diagrams, lesson build-prep callouts,
    syntax highlighting fixes, stale claims removed
  • v0.2.43

    Release v0.2.43
    
    - fix(session): persist sessions in CGI isolation mode (#108) — pool worker now flushes $_SESSION between dispatches; SessionManager skips its lifecycle when superglobals(true) + processIsolation(true) (subprocess owns sessions); App::mintCgiSession() emits Set-Cookie on first-visit since PHP's session module can't reach userspace setcookie() under uopz.
  • v0.2.42

    Release v0.2.42
    
    - Fix #103: variadic-defensive App::dispatchTaskCallback() for OpenSwoole
      22.x's two task-handler signatures (2-arg coroutine + 4-arg legacy).
      Prod workers no longer crash with ArgumentCountError under default
      task_enable_coroutine => true. Pinned by 10 unit tests.
    - Acknowledge #104: sibling-package zealphp-mongodb v0.2.8-v0.2.11
      (BSONDocument drop-in, MongoDB\Driver\* polyfills, pass-by-ref fixes).
      No framework change; documented upgrade path in CHANGELOG.
    
    Also carries the intended v0.2.41 release content (FCGI worker pool
    default, WP-on-proc regression fix, ZealAPI helpers) — v0.2.41 was
    mis-tagged on Packagist at orphan commit 0372c3a. Skip v0.2.41;
    composer require sibidharan/zealphp:^0.2.42 if already installed.
  • v0.2.41

    Release v0.2.41
    
    - ZealPHP-native FCGI-style worker pool — cgiMode('pool') is now the
      framework default. CGI bridge per-request cost drops ~30–50 ms (proc)
      to ~1–3 ms (pool). cgiMode('fork') removed entirely.
    - FPM-style $GLOBALS snapshot/restore in pool_worker.php.
    - WordPress on cgiMode('proc') regression fix (issue #18): autoload
      gated behind opt-in App::cgiSubprocessAutoload(true), default off
      restores v0.2.0 zero-overhead subprocess start.
    - ZealAPI helpers upstreamed from labs-dashboard-web (PR #100):
      resolveClubParam(), failAs(Throwable), json() made public.
  • v0.2.40

    Release v0.2.40
    
    Production hardening + Memcached + federated WebSocket rooms.
    
    Highlights
    - Production hardening pass on the Redis backend surface — closed 3
      critical (FD-reuse race in WSRouter, HMAC-signed L1 invalidations,
      rediss:// TLS) + 10 medium gaps. Default behaviour preserved across
      all 13 fixes.
    - Memcached backend for Store + Counter (Store::BACKEND_MEMCACHED,
      Counter::BACKEND_MEMCACHED) with ZEALPHP_MEMCACHED_SERVERS env var
      + array config; phpredis + predis driver validated for SUBSCRIBE
      under HOOK_ALL.
    - Federated WebSocket Rooms (P1.1 of v0.3.0 roadmap, landed early) —
      WSRouter::room(name): Room with first-class join/leave/push/onMessage/
      onPresence + cluster-wide membership via shared Store table + one
      PSUBSCRIBE pattern subscriber per worker.
    - Three-backend Store facade — Store::BACKEND_TABLE / BACKEND_REDIS /
      BACKEND_TIERED, plus Cache::getOrCompute read-through with null
      sentinel.
    - v0.3.0 early helpers — App::parallel / parallelLimit, App::onSignal,
      App::stats, HTTP::get/post/put/delete, App::addProcess for sidecars.
    - Real end-to-end async integration tests for pub/sub + streams
      delivery (RedisPubSubFederationTest) + redis-pubsub coverage pass.
    - Fixed route/demo_rooms.php deferring WSRouter::init to onWorkerStart
      (would crash production deploys with ZEALPHP_STORE_BACKEND=redis).
    
    CI: every required check green, codecov/patch passed at 79.03%.
  • v0.2.39

    Release v0.2.39 — pluggable Store/Counter backends
    
    Phase 1 of the pluggable-backend program. `Store` and `Counter` now
    delegate to backend instances behind their existing static/instance APIs.
    `OpenSwoole\\Table` / `OpenSwoole\\Atomic` remain the default (nanosecond
    hot path); flip to Redis/Valkey for cross-node shared state with one line
    in app.php (`Store::defaultBackend(Store::BACKEND_REDIS)`) or the
    `ZEALPHP_STORE_BACKEND=redis` env var. Every existing handler call site
    keeps working unchanged.
    
    Pub/sub + Streams primitives (`Store::publish` / `App::onPubSub` /
    `Store::publishReliable` / `App::onReliableMessage`) ship in this release
    backed by RedisPubSub + RedisStreams lifecycle classes. Phase 3 pub/sub
    design empirically de-risked via three committed spikes (in-process,
    cross-process, cross-host @ 0.53 ms median via wireguard).
    
    Tagged retroactively at d854b99 (the 'complete v0.2.39 version-ref bumps'
    commit) — the v0.2.39 content was authored but never tagged when work
    moved on to v0.2.40. Master branch is behind d854b99; the v0.2.40 release
    on top of v0.2.39 brings everything to master via PR #87.
    
    Full notes: CHANGELOG.md [0.2.39] section (kept verbatim within the
    v0.2.40 collapsed entry).
  • v0.2.38

    Release v0.2.38 — Apache + nginx parity wave
    
    Security:
    - referer DNS-label wildcard (closes example.evil.com over-match)
    - symlink escape via static serving (realpath docroot containment)
    - mod_expires no longer caches 4xx/5xx
    - double-encoded traversal (%252e%252e -> 400)
    - multi-range DoS cap (CVE-2011-3192 class)
    - explicit plaintext-htpasswd rejection + DES salt alphabet fix
    - error responses no longer leak prior handler headers
    
    Added:
    - ConditionalRequest evaluator (RFC 9110 If-Match/Unmod/None-Match/Mod-Since precedence + 412)
    - MimeResolver (multi-suffix Content-Type/Encoding/Language a la mod_mime)
    - ContentEncoding/ContentLanguage middleware
    - per-key ConcurrencyLimit (Store-backed, proxy-aware) + dry-run + configurable status
    - RateLimit burst/nodelay/dry-run/configurable-status, App::clientIp() keying
    - HostRouter trailing-wildcard + regex server_name + Host-400, IPv6 host parse
    - HeaderMiddleware nginx-style status-conditional add_header + always opt-out
    - Range If-Range HTTP-date; sendFile multi-range (206 multipart)
    - ExpiresMiddleware dual-header + M-base + error-suppress + clamp
    - Two source-diff audit docs: docs/apache-parity-audit.md, docs/nginx-parity-audit.md
    
    Changed:
    - HeaderMiddleware default = status-conditional (mild BC; per-rule always to restore)
    - Compression Vary merges instead of overwriting, q=0 refused, weak-ETag on compress
    - Redirect QSA merges query with & when target has one
    - BodySizeLimit chunked enforcement + 0 = unlimited
    - App::$limit_request_fields enforced (400 on excess); STANDARDS.md adds OpenSwoole-governed surfaces
    
    Tests: 1962 unit, Infection covered-MSI 92% (gate 92), plain-MSI 90% (gate 88).
    PR #38.
  • v0.2.37

    Release v0.2.37
    
    - BasicAuth APR1 (apr_md5) digest fix: byte-reversed encoding could never verify a real htpasswd -m hash; now pinned against Apache htpasswd/openssl oracles
    - Infection covered-MSI 65% -> 95% (1680/1763 killed; 83 survivors all provably-equivalent, catalogued in STANDARDS.md); gate ratcheted to 88/92
    - Apache httpd core-logic diff + non-support register (ProxyPass/TLS/WebDAV/CGI/mod_rewrite/.htaccess/...)
    - Runnable HTTP fuzz harnesses: radamsa (500 muts, 0 hangs/0 leaks), gabbi (7/7), slowhttptest; wired into CI (fuzz.yml)
  • v0.2.36

    Release v0.2.36
    
    - 405 Method Not Allowed + Allow header (RFC 9110 §15.5.6); implicit document-root routes scoped to GET/POST (Apache static-handler parity)
    - Mutation Score Indicator badge in README, auto-refreshed from CI on master
    - Conformance: symlink-escape refusal + chunked-framing edge cases (extension/trailer/leading-zeros)
    - STANDARDS.md advanced-testing roadmap (Infection / http-garden / Radamsa / slowhttptest / Gabbi)
  • v0.2.35

    Release v0.2.35
    
    HTTP/1.1 + static-serving conformance:
    - RFC 9112 §3.2 Host enforcement: HTTP/1.1 without Host -> 400 (1.0 exempt).
    - StaticServingConformanceTest: traversal corpus confined to docroot, dotfiles
      never served, autoindex off, MIME + conditional 304.
    - Host-rule + response-splitting (header() CR/LF/NUL) conformance.
    - STANDARDS.md request-line/Host/static matrix + OpenSwoole deviation register.
  • v0.2.34

    Release v0.2.34
    
    Standards conformance + Apache/nginx parity:
    - Conformance suites: IANA status (exhaustive), RFC 6265 cookies, RFC 9110 IMF-date,
      HTTP/1.1 framing & request smuggling (RFC 9112 §6-§7), live traversal proof.
    - CI gates: 80% coverage floor (codecov), Infection mutation testing (minMsi 55 /
      covered 60), perf-regression smoke. STANDARDS.md catalogue.
    - Middleware: ScopedMiddleware, RequestHeaderMiddleware, MergeSlashesMiddleware,
      BodySizeLimitMiddleware, RefererMiddleware, ReturnMiddleware.
    - Fixes: #23 session pipe-format cross-server parity, #25 .php URLs 404 not 403.
  • v0.2.33

    Release v0.2.33
    
    Fixed:
    - #16 RedisSessionHandler is now coroutine-safe (one \Redis connection per
      coroutine instead of a shared socket) — resolves session corruption under
      concurrent/rapid sequential requests with a shared handler.
  • v0.2.32

    Release v0.2.32
    
    Apache/mod_php parity wave 2:
    - Built-in overrides: php_sapi_name, filter_input/filter_input_array, header_register_callback, error_log
    - $_SERVER completeness: GATEWAY_INTERFACE, REQUEST_SCHEME, HTTPS
    - Directive middleware: RedirectMiddleware (mod_alias), SetEnvIfMiddleware (mod_setenvif)
    - Config: ServerTokens (X-Powered-By), FileETag, default_mimetype
    Fixes:
    - #20 void return discarded buffered output
    - #21 unset($g->session[k]) not persisted through custom handler
  • v0.2.31

    Release v0.2.31
    
    - phpinfo() now renders styled HTML (Apache/mod_php parity) via ZealPHP\Diagnostics\PhpInfo + uopz override
    - App::onWorkerStop() per-worker shutdown hook
    - Fix #18: API routes keep DOCUMENT_ROOT at the web root (not /api); SCRIPT_NAME/PHP_SELF/SCRIPT_FILENAME parity
    - Fix #19: session_regenerate_id() is custom-handler-aware — migrates data + emits new-ID cookie (Redis/Valkey OAuth flows)
    - Test coverage ~29% -> ~80% combined; real WebSocket integration tests
  • v0.2.30

    Release v0.2.30 — full superglobal aliasing ($g->get IS $_GET in superglobals mode) + issue #17 CLI/CGI fixes