Skip to content

Events

Listeners are callables registered during bootstrap. Custom events can carry any payload:

use function Naf\{event, log};

event()->listen('product.created', function (object $product) {
    log()->info('Product created', ['id' => $product->id]);
});

// After your application creates a product:
event()->dispatch('product.created', $product);

listen($event, $listener, $priority = 0) runs higher priorities first. dispatch() returns an array of listener results. Use closures or [ListenerClass::class, 'handle']; NAF constructs class-based listeners through the default container.

Request lifecycle

The following events describe the normal HTTP path. Payload order is part of the API.

Event Payload When
request.start $request After creating and registering the request in App::run()
route.matching $uri, $method Before searching routes
route.matched $route array After finding a match
route.not_found $uri, $method When no route matches
controller.calling $request, $controller, $action Before invoking the handler; controller is null for a closure
controller.called $request, $controller, $action, $response After invoking the handler
exception $exception When request handling throws
response.send $response During response finalization
response.header $response Before sending HTTP headers
response.body $response Before writing the body, after headers
response.end $response After writing the body

request.end and request.body are declared constants but are not dispatched by the current request path. There is no response.sending event.

Change a response

PSR-7 responses are immutable: withHeader() returns a new response. Return it from a response.header listener:

use Naf\Core\Event;
use Psr\Http\Message\ResponseInterface;
use function Naf\event;

event()->listen(Event::RESPONSE_HEADER, function (ResponseInterface $response) {
    return $response->withHeader('X-Application', 'My NAF app');
});

The last returned response is used. Returning a response from controller.called or response.send does not replace the response being sent. The exception hook also supports returned responses; see Errors and aborting.

The response-body and response-end events are too late to change headers. Raw fatal-error emission can bypass this normal event path; do not depend on these listeners for cleanup that must run after every possible PHP failure.