Best way to handle register_shutdown_function

Hello there.
I’m trying to write a piece of code to best handle extreme-cases where my API runs out of memory handling a request in PHP 7 using the Slim 3 framework. At the moment I have the following snippet at the very start of my application before Slim is even used/started/initialized.

$fatal_error_callback = function() use ($logger) {
    $error = error_get_last();
    if (!empty($error))
        # ... more code for loggging the issue ...
        # return a message to the user.
        header('Content-Type: application/json');
        header('Status', 'Error');
        $responseData = array(
            'result' => 'error',
            'message' => 'Request was too large, please find an alternative.',
        die(json_encode($responseData, JSON_UNESCAPED_SLASHES));


I would like to be able to get access to the slim request object from within this handler if it exists, so that I can get access to information about the request the user was trying to make. This way I could suggest alternative ways the user could get the information they want over multiple requests. I have a singleton for being able to get the slim app object that was being used, but I understand that either you cant get the request from this, or that getting it would be pointless.

My current plan is to add a new piece of middleware that executes before the request is handled, that registers details of the request, such as the route-name, into an area that can be globally accessed, such a singleton, static method, or global variable, which I could then access from the shutdown handler, but was wondering if there was a better way that was more “slim like”.

You can use the built in functions for handle errors in Slim.

You can use this one and check the doc for other use cases.

I have already registered the slim error handlers (below) but they don’t seem to catch when you run out of memory (fatal error), which is why I have a registered shutdown function. Perhaps there is some issue with how I have registerd them.

        $app = SiteSpecific::getSlimApp();
        // set the error handlers
        $container = $app->getContainer();
        $errorHandler = function($request, $response, $args) {
            return $response->withStatus(500)
                            ->withHeader('Content-Type', 'application/json')
                            ->write('Something went wrong!');
        // This is returned when the route exists but the method, such as POST or PATCH does
        // not exist for it.
        $methodNotAllowedHandler = function($request, $response, $args) {
            $ex = new Exception("That method is not allowed.", HTTP_METHOD_NOT_ALLOWED);
            return SiteSpecific::getErrorResponseForException($ex, $response);
        $container['errorHandler'] = function ($container) use ($errorHandler) {
            return $errorHandler;
        // Runtime PHP errors (PHP 7+ only)
        $container['phpErrorHandler'] = function ($container) use ($errorHandler) {
            return $errorHandler;
        $container['notAllowedHandler'] = function ($container) use ($methodNotAllowedHandler) {
            return $methodNotAllowedHandler;
        $container['notFoundHandler'] = function ($container) {
            // need to use an annonymous class here due to the fact that need to use $container
            // at last possible second.
            return new class($container) {
                private $m_container;
                public function __construct($container)
                    $this->m_container = $container;
                public function __invoke($request, $response) 
                    $ex = new Exception("That method/route does not exist.", HTTP_NOT_FOUND);
                    return SiteSpecific::getErrorResponseForException($ex, $response);

Which versino of Slim are you using?
In PHP7 all errors that implements Throwable can be caught.
I recommend you to se BooBoo package if you’re having trouble with it.

You can see an example of implementation here:
Register in the container
Call it before running the app