【问题标题】:Cache entire HTML response in Laravel 5在 Laravel 5 中缓存整个 HTML 响应
【发布时间】:2015-10-01 05:29:53
【问题描述】:

我正在尝试使用中间件缓存整个响应

我遵循的步骤

生成了两个中间件

  • AfterCacheMiddleware
  • BeforeCacheMiddleware

在 BeforeCacheMiddleware 中:

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

在 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;
}

kernal.php的$routeMiddleware数组中注册的中间件

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

在 routes.php 中,我像这样调用这个虚拟路由

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

问题:

只有 cachebefore 中间件被调用。 cacheafter 根本没有被调用

谁能建议我在这里缺少什么?

【问题讨论】:

    标签: php caching laravel-5 middleware


    【解决方案1】:

    我在自己寻找解决方案时发现了这个问题。我知道有进行此缓存的 Flatten 包,但我找不到如何自己执行此操作的好例子。此问题中的解决方案尝试包含对我自己的解决方案有用的想法,尽管我选择仅使用单个中间件。

    虽然问题很老,提问者可能不再需要答案,但我会在这里分享我的解决方案,因为我觉得 SO(和互联网)缺乏 Laravel 5 的缓存示例。我会尽量解释我可以,但最重要的是,你应该熟悉 Laravel 5 中的 RoutingCachingMiddlewaring。所以这里有解决方案:

    中间件

    创建一个中间件,这些中间件通常放在app/Http/Middleware文件夹中,我将文件称为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;
        }
    }
    

    根据您的需要更改$key...您拥有所有带有所有参数的$request...如果您将手动清除缓存并且不希望它,请将Cache::put($key, $value, $minutes)更改为Cache::forever($key, $value)永远过期。

    在大多数情况下使用 URL 作为存储缓存的键是可用的,但人们可能会想到更适合某个项目的东西。

    注册中间件

    通过将中间件添加到$routeMiddleware 数组中,在app/Http/Kernel.php 中注册它,如下所示:

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

    当然,如果您将\App\Http\Middleware\CachePage 放在其他地方或给它取了另一个名字,您应该更改它。此外,密钥名称 cachepage 由您决定 - 它将用于调用中间件。

    用法

    在您的app/Http/routes.php 中使用中间件,就像auth 或其他中间件一样,例如,您可以为所有应该缓存的页面创建一个路由组:

    Route::group(['middleware' => 'cachepage'], function () 
    {
        Route::get('/', 'HomeController@home');
        Route::get('/contacts', 'SectionController@contacts');
    });
    

    【讨论】:

    • return Cache::get($key); 似乎不再适用于 Laravel 5.3。请改用return response(Cache::get($key));
    • 我在自己的缓存包中使用了类似的逻辑:github.com/GlaivePro/CachePage
    【解决方案2】:

    中间件列表必须在方括号内:

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

    【讨论】:

    • 这是对“为什么我的解决方案无法调用第二个中间件?”问题的答案。我添加了一个完整的解决方案,不同于提问者在单独答案中的尝试。
    猜你喜欢
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 2016-06-11
    • 2015-05-17
    • 1970-01-01
    相关资源
    最近更新 更多