Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache entire HTML response in Laravel 5

I am trying to cache entire response using middleware

Steps i followed

Generated two middleware

  • AfterCacheMiddleware
  • BeforeCacheMiddleware

With in BeforeCacheMiddleware:

public function handle($request, Closure $next)
{            
        $key = $request->url();
        if(Cache::has($key)) return Cache::get($key);
        return $next($request);
}

With in AfterCacheMiddleware

public function handle ($request, Closure $next)
{       
    $response = $next($request);
    $key = $request->url();       
    if (!Cache::has($key)) Cache::put($key, $response->getContent(), 60);
    return $response;
}

Registered middleware in $routeMiddleware array of kernal.php

'cacheafter' => 'App\Http\Middleware\AfterCacheMiddleware',
'cachebefore' => 'App\Http\Middleware\BeforeCacheMiddleware',

With in routes.php i am calling this dummy routes like this

Route::get('middle', ['middleware' => 'cachebefore', 'cacheafter', function()
{
    echo "From route";
}]);

Issue:

only cachebefore middleware is getting called. cacheafter is not getting called at all

Can anyone suggest what i am missing here ?

like image 905
Muhammed Khalander Avatar asked Dec 18 '22 23:12

Muhammed Khalander


1 Answers

I found this question while I was looking for solution myself. I am aware that there is the Flatten package which does this caching, but I couldn't find nice examples on how to do this by myself. The solution attempt in this question contains ideas that were useful for my own solution, although I chose to go with a single middleware only.

Although the question is old and asker probably doesn't need the answer anymore, I will share my solution here as I feel that SO (and internet) lacks this caching sample for Laravel 5. I will try to explain as much as I can, but for most benefit you should be familiar with Routing, Caching and Middlewaring in Laravel 5. So here goes the solution:

Middleware

Create a middleware, those are usually placed in app/Http/Middleware folder and I will call the file CachePage.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;
use Cache;

class CachePage
{
    public function handle($request, Closure $next)
    {
        $key = $request->fullUrl();  //key for caching/retrieving the response value

        if (Cache::has($key))  //If it's cached...
            return response(Cache::get($key));   //... return the value from cache and we're done.

        $response = $next($request);  //If it wasn't cached, execute the request and grab the response

        $cachingTime = 60;  //Let's cache it for 60 minutes
        Cache::put($key, $response->getContent(), $cachingTime);  //Cache response

        return $response;
    }
}

Change $key according to your needs... You have all the $request with all the parameters... Change Cache::put($key, $value, $minutes) to Cache::forever($key, $value) if you will clear the cache manually and don't want it to ever expire.

Using the URL as key for storing cache is usable in most cases, but one might think of something more appropriate for a certain project.

Registering middleware

Register it in app/Http/Kernel.php by adding the middleware to $routeMiddleware array like this:

protected $routeMiddleware = [
    /* ...  */
    /* Other middleware that you already have there */
    /* ... */
    'cachepage' => \App\Http\Middleware\CachePage::class,
];

Of course, you should change \App\Http\Middleware\CachePage if you placed it elsewhere or gave it another name. Also the key name cachepage is up to you - it will be used to invoke the middleware.

Usage

In your app/Http/routes.php use the middleware just like auth or other middlewares, for example, you might make a route group for all the pages that should be cached:

Route::group(['middleware' => 'cachepage'], function () 
{
    Route::get('/', 'HomeController@home');
    Route::get('/contacts', 'SectionController@contacts');
});
like image 164
Džuris Avatar answered Dec 21 '22 13:12

Džuris