Laravel Selective Caching

拟墨画扇 提交于 2019-12-11 03:05:34

问题


I'm developing one of my first applications with the Laravel 4 framework (which, by the way, is a joy to design with). For one component, there is an AJAX request to query an external server. The issue is, I want to cache these responses for a certain period of time only if they are successful.

Laravel has the Cache::remember() function, but the issue is there seems to be no "failed" mode (at least, none described in their documentation) where a cache would not be stored.

For example, take this simplified function:

try {
    $server->query();
} catch (Exception $e) {
    return Response::json('error', 400);
}

I would like to use Cache::remember on the output of this, but only if no Exception was thrown. I can think of some less-than-elegant ways to do this, but I would think that Laravel, being such an... eloquent... framework, would have a better way. Any help? Thanks!


回答1:


I found this question, because I was looking for an answer about this topic.

In the meanwhile I found a solution and like to share it here:
(also check out example 2 further on in the code)

<?php
/**
 * Caching the query - Example 1
 */

function cacheQuery_v1($server)
{
    // Set the time in minutes for the cache
    $minutes = 10;

    // Check if the query is cached
    if (Cache::has('db_query'))
    {
        return Cache::get('db_query');
    }

    // Else run the query and cache the data or return the 
    // error response if an exception was catched
    try
    {
        $query = $server->query(...);
    }
    catch (Exception $e)
    {
        return Response::json('error', 400);
    }

    // Cache the query output
    Cache::put('db_query', $query, $minutes);

    return $query;
}


/**
 * Caching the query - Example 2
 */

function cacheQuery_v2($server)
{
    // Set the time in minutes for the cache
    $minutes = 10;

    // Try to get the cached data. Else run the query and cache the output.
    $query = Cache::remember('db_query', $minutes, function() use ($server) {
        return $server->query(...);
    });

    // Check if the $query is NULL or returned output
    if (empty($query))
    {
        return Response::json('error', 400);
    }

    return $query;
}

I recommend you to use Laravel's Eloquent ORM and/or the Query Builder to operate with the Database.

Happy coding!




回答2:


This is what worked for me:

if (Cache::has($key)) {
    $data = Cache::get($key);
} else {
    try {
        $data = longQueryOrProcess($key);
        Cache::forever($key, $data); // only stored when no error
    } catch (Exception $e) {
        // deal with error, nothing cached
    }
}

And of course you could use Cache::put($key, $data, $minutes); instead of forever




回答3:


We're working around this by storing the last good value in Cache::forever(). If there's an error in the cache update callback, we just pull the last value out of the forever key. If it's successful, we update the forever key.



来源:https://stackoverflow.com/questions/16976455/laravel-selective-caching

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!