Repository navigation
v0.2.4 — Routes an application can take back, and safer streamed output
An application could add routes but never take one back, and a controller bound in the container was ignored: the dispatcher always constructed a fresh instance. Naf\Core\Route::remove(string $name): bool now removes a named route from matching and reports whether it existed, and the dispatcher prefers a bound target class before falling back to building an unbound one. A bound object that does not have the route's action is reported as a DispatcherException instead of failing obscurely. Together these let a host or a plugin replace a route and its controller deliberately, rather than by registering something on top and hoping for the ordering.
This release also carries the integration hardening prepared for v0.2.4:
- A container service whose factory legitimately returns
nullwas treated as absent, because presence was checked withisset(). It is nowarray_key_exists(), so a null service stays registered and resolvable.ContainerExceptionadditionally chains the original throwable instead of only copying its message. ResponseEmittermaterialised the whole response body into memory before writing it. It now streams the body in 8 KiB chunks, rewinding a seekable stream first, so a large download no longer grows the PHP heap by its own size.- An object callable registered with the event manager could be mistaken for a class/method pair and break. The check now requires a string first element and an otherwise non-callable array before treating it as a class reference.
Debug output is narrower, and this can change what you see. ErrorHandler previously showed the debug view for any environment that was neither PROD nor TEST, so a misspelled or custom APP_ENV silently opened detailed error pages. It now shows that view only for Environment::DEV. If you run under an environment name other than dev and relied on debug output, switch that environment to dev; no other action is required.
Validation: the tagged commit passed framework CI, and its tree passed the suite with 137 tests and 280 assertions. The new behaviour is covered in RouteTest, DispatcherTest and IntegrationHardeningTest.
Version note: Route::remove() is additive. The dispatcher change is visible only where a controller class is bound in the container, which previously had no effect. Dependency constraints are unchanged.