Execute an action after Laravel returns response
Tags: php, laravel
Published: 2020-02-13 15:28:54

---
title: Execute an action after Laravel returns response
published: true
description: After a response has been sent and the client connection closed, the PHP process is still alive to continue execution.
tags: php, laravel,
---

 In this article, we want to explore the various ways we can execute small tasks or actions in laravel after a response is sent. You will see how these tasks are processed after the application responds to an incoming request. 
 
 Let’s take a peep at the entry point for all requests to a Laravel application, which is the `public/index.php` file. We’re only interested in the part where the request is handled through the kernel and a response is sent back to the client (e.g browser).


    // public/index.php
    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
    
    $response = $kernel->handle(
        $request = Illuminate\Http\Request::capture()
    );
    
    $response->send();
    
    $kernel->terminate($request, $response);

An Http kernel instance is resolved from the laravel container and is used to handle the incoming request, and then returns a response. This response is sent back to the client, by calling the `$response→send()` method on the response variable gotten from handling the request. The `send` method outputs the content and sends defined headers for the response, it then tries to close the output buffering by ending the open connection with the client. In a case PHP FPM is used, the `fastcgi_finish_request` is used to close the connection.


> The `fastcgi_finish_request` function flushes all response data to the client and finishes the request. This allows for time-consuming tasks to be performed without leaving the connection to the client open. Read more [here](https://www.php.net/manual/en/function.fastcgi-finish-request.php)

Just after the `$response→send()` line, we have the `$kernel→terminate($request, $response)` line next. We know the former sends a response, but what about that of the later.  The latter expression seems self-explaining, indicating the application Http kernel is terminating the request and response.

After a response has been sent and the client connection closed, the PHP process is still alive to continue execution. In this case, the application Http kernel `terminate` method can be used to run little tasks. To run such little task or action, we can achieve them using:


- Terminable Middleware
- Terminating Callbacks


```
// vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php
    public function terminate($request, $response)
    {
        $this->terminateMiddleware($request, $response);
        $this->app->terminate();
    } 
```

The above code snippet happens to be the content of the kernel `terminate` method. The first line calls the method `terminateMiddleware` on the application Http kernel, and the second calls the `terminate` method on the application container, which runs through all the terminating callbacks and execute them.


## Terminable Middlewares

  In laravel, we can define middlewares to intercept incoming requests and perform little tasks before reaching the main controller logic. This middleware class usually have a `handle` method to run the task. We can also define a `terminate` method on this middleware class, this method will perform little tasks after the response has been sent to the client. A middleware class with the `terminate` method can be described as a Terminable Middleware. 
  

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class AfterResponseMiddleware
    {
        public function handle($request, Closure $next)
        {
            return $next($request);
        }
    
        public function terminate($request, $response)
        {
            // Perform tasks after response as been sent to the client
        }
    }

 
Remember the method `terminateMiddleware` we found being used in the application Http kernel `terminate` method. This method is what calls the terminate method on any terminable middleware.

So in what case would one need to use a terminable middleware: Activity logging, Request logging and Session tracking.


## Terminating Callbacks

Terminating callbacks are executed just after all terminable middlewares have been executed. These callbacks are functions registered to the laravel application. The snippet below, shows how to register a terminating callback:


    App::terminating(function () {
    });
    
    app()->terminating(function () {
    
    });

From the above code block, we can observe the use of a `terminating` method to register the callback function. This terminating `method` also exists in the application container. When the `terminate` method is called after the terminable middleware execution, all the terminating callbacks are then executed.

```
  foreach ($this->terminatingCallbacks as $terminating) {
      $this->call($terminating);
  }
```

A pretty much use case for a terminating callback is reporting on guzzle requests made during an Http request in laravel. Also, [Mohamed Said](https://twitter.com/themsaid) contributed a new method that allows a job to dispatch after the response is sent back to the client, he wrote about this on his blog [here](https://divinglaravel.com/running-a-task-after-the-response-is-sent). This is needed to dispatch a short job instantly instead of sending it to the regular queue system.


    ShortInstantJob::dispatchAfterResponse();

The `dispatchAfterResponse` attaches the Job class as a terminating callback to the laravel application which is then executed when the application `terminate` is called.


## Conclusion

Right here, we have seen the possible ways there is to execute actions after a response is sent in laravel and how this is achieved. Note that the kind of actions or tasks we want to execute after returning a response are meant to be a short-lived process.