|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to this project are documented in this file. |
| 4 | + |
| 5 | +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), |
| 6 | +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
| 7 | + |
| 8 | +## [Unreleased] |
| 9 | + |
| 10 | +## [2.0.0] - 2026-06-09 |
| 11 | + |
| 12 | +A major modernisation release. The monolithic router is decomposed into focused, |
| 13 | +fully-typed components, several long-standing bugs are fixed, and the public API |
| 14 | +is tidied. The route **registration** API (`get()`, `post()`, `group()`, |
| 15 | +`name()`, `route()`, `filter()`, …) is unchanged, so most applications upgrade |
| 16 | +with little or no code change. See the |
| 17 | +[upgrade guide](./docs/upgrading-1.x-to-2.0.md) for the breaking changes and |
| 18 | +migration steps. |
| 19 | + |
| 20 | +### Added |
| 21 | + |
| 22 | +- A `Route` value object and a `RouteCollection`, replacing the array-based route |
| 23 | + table. |
| 24 | +- Focused collaborators: `Matching\PatternRegistry`, `Matching\RouteMatcher`, |
| 25 | + `Dispatch\Dispatcher`, `Dispatch\MiddlewareRunner`, `Resolver\ControllerResolver`, |
| 26 | + `Resolver\ParameterResolver`, `Link\FileLinkHandler`, `Cache\RouteCache`, |
| 27 | + `Http\RequestContext`. |
| 28 | +- `setNotFoundHandler()` to define the 404 handler. |
| 29 | +- `getCurrentController()`, `getCurrentControllerMethod()` and |
| 30 | + `getCurrentArguments()` accessors. |
| 31 | +- First-class [PSR-11](https://www.php-fig.org/psr/psr-11/) container support. |
| 32 | +- Path-traversal protection for directory links. |
| 33 | +- A comprehensive test suite (90%+ line coverage), a CI workflow (PHP 8.1–8.4, |
| 34 | + PHPStan at max, PHP-CS-Fixer, and a coverage floor), and full English |
| 35 | + documentation under `docs/`. |
| 36 | + |
| 37 | +### Changed |
| 38 | + |
| 39 | +- **Minimum PHP version is now 8.1.** |
| 40 | +- `resolve()` returns a `Route` object (or `null`) instead of an array. |
| 41 | +- Middleware returning `null` now halts the pipeline cleanly instead of calling |
| 42 | + `exit()`. |
| 43 | +- The client IP is detected from `$_SERVER` instead of `getenv()`. |
| 44 | +- Large linked files are streamed through the PSR-7 response instead of |
| 45 | + `readfile()` + `exit()`. |
| 46 | +- Internally: private methods renamed to camelCase, all properties/parameters/ |
| 47 | + return types declared, PSR-12 applied, and PHPDoc rewritten to match the code. |
| 48 | + |
| 49 | +### Deprecated |
| 50 | + |
| 51 | +- `error_404()` — use `setNotFoundHandler()`. The alias still works. |
| 52 | + |
| 53 | +### Removed |
| 54 | + |
| 55 | +- The `INITPHP_ROUTER_CURRENT_ARGUMENTS`, `INITPHP_ROUTER_CURRENT_CONTROLLER` and |
| 56 | + `INITPHP_ROUTER_CURRENT_METHOD` global constants (use the `getCurrent*()` |
| 57 | + accessors). |
| 58 | +- All `exit()` / `die()` calls from library code. |
| 59 | + |
| 60 | +### Fixed |
| 61 | + |
| 62 | +- IP-restricted route groups never matched, even for an allow-listed client. |
| 63 | +- Default ports (80/443) were never dropped from generated URIs. |
| 64 | +- The router could only be dispatched once per process (unguarded global |
| 65 | + constants raised "Constant already defined" on a second dispatch). |
| 66 | +- Directory links were vulnerable to path traversal (e.g. `/assets/../secret`). |
| 67 | +- `resolve()` corrupted internal state for `LINK` routes and could fatal when |
| 68 | + called before `dispatch()`. |
| 69 | +- The cache-read error referenced the wrong configuration key, and a failed cache |
| 70 | + write could throw from the destructor. |
| 71 | +- Controller name resolution used a whitespace `ltrim()` mask instead of a |
| 72 | + backslash mask. |
| 73 | +- Parameter resolution silently dropped a required built-in parameter, causing a |
| 74 | + later `ArgumentCountError`. |
| 75 | +- Multi-slash path normalisation and the fragile `array_merge_recursive`-based |
| 76 | + options merge. |
| 77 | + |
| 78 | +### Security |
| 79 | + |
| 80 | +- Directory links now verify the resolved real path stays inside the link root, |
| 81 | + preventing path traversal. |
| 82 | +- Route-cache `unserialize()` is hardened with `allowed_classes: false`. |
| 83 | + |
| 84 | +[Unreleased]: https://github.com/InitPHP/Router/compare/2.0.0...HEAD |
| 85 | +[2.0.0]: https://github.com/InitPHP/Router/compare/1.2.1...2.0.0 |
0 commit comments