Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Cache:: Best Practices

PHP Colleagues:

This question relates to best practices for using Laravel Cache.

The central objective is to reduce the number of accesses to the database for all the usual performance-related reasons. The application is a read-intensive news site with perhaps a dozen controllers at most, mostly resource-type.

Are there any documented best practices for the application design? It seems obvious to me that since Cache:: is a one-line statement, it's easy to drop this into the controllers -- either return the cached data or call the model and cache the results. And invalidate the cache (maybe with an eager reload) when requests update the model. But is that a good practice?

Here's a first look at doing this in the controller

/**
 * Retrieve listing of the gallery resource.
 *
 * @uses GET /gallery to return all image_collections.
 *
 * @param int $id The gallery id
 *
 * @return Response - Contains a HTTP code and a list of articles.
 */
public function index()
{
    $response_data = array();
    $response_code = 200;

    // TRY TO RETURN A CACHED RESPONSE
    $cache_key = "gallery_index";
    $response_data = Cache::get($cache_key, null);

    // IF NO CACHED RESPONSE, QUERY THE DATABASE
    if (!$response_data) {
        try {
            $response_data['items'] = $this->gallery->all();
            Cache::put($cache_key, $response_data, Config::get('app.gallery_cache_minutes'));
        } catch (PDOException $ex) {
            $response_code = 500;
            $response_data['error'] = ErrorReporter::raiseError($ex->getCode());
        }
    }

    return Response::json($response_data, $response_code);
}

I've heard the suggestion that you could use Laravel Route Filters to cache the responses, but I can't quite get my head around the idea.

Thoughts? References? Examples?

Thanks to all, Ray

like image 541
Ray Paseur Avatar asked Mar 26 '15 23:03

Ray Paseur


People also ask

How does Laravel manage cache?

Your application's cache configuration file is located at config/cache.php . In this file, you may specify which cache driver you would like to be used by default throughout your application. Laravel supports popular caching backends like Memcached, Redis, DynamoDB, and relational databases out of the box.

Where does Laravel store cached data?

The cache configuration is located at app/config/cache. php . In this file you may specify which cache driver you would like used by default throughout your application. Laravel supports popular caching backends like Memcached and Redis out of the box.

Does Laravel support caching explain in detail?

Yes, Laravel provides support for popular caching backends like Memcached and Redis. By default, Laravel is configured to use file cache driver, which is used to store the serialized or cached objects in the file system. For huge projects, it is suggested to use Memcached or Redis.


1 Answers

Many people do this differently but when best practices is a concern I believe the best place to do caching is in your repository.

Your controller shouldn't know too much about the data source I mean whether its coming from cache or coming from database.

Caching in controller doesn't support DRY (Don't Repeat Yourself) approach, because you find yourself duplicating your code in several controllers and methods thereby making scripts difficult to maintain.

So for me this is how I roll in Laravel 5 not so different if are using laravel 4:

//1. Create GalleryEloquentRepository.php in App/Repositories

<?php namespace App\Repositories;

use App\Models\Gallery;
use \Cache;

/**
 * Class GalleryEloquentRepository
 * @package App\Repositories
 */
class GalleryEloquentRepository implements GalleryRepositoryInterface
{

    public function all()
    {
        return Cache::remember('gallerys', $minutes='60', function()
        {
            return Gallery::all();
        });
    }


    public function find($id)
    {
        return Cache::remember("gallerys.{$id}", $minutes='60', function() use($id)
        {
            if(Cache::has('gallerys')) return Cache::has('gallerys')->find($id); //here am simply trying Laravel Collection method -find

            return Gallery::find($id);
        });
    }

}

//2. Create GalleryRepositoryInterface.php in App/Repositories

<?php namespace App\Repositories;

/**
 * Interface GalleryRepositoryInterface
 * @package App\Repositories
 */
interface GalleryRepositoryInterface
{

    public function find($id);

    public function all();
}

//3. Create RepositoryServiceProvider.php in App/Providers

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

/**
 * Class RepositoryServiceProvider
 * @package App\Providers
 */
class RepositoryServiceProvider extends ServiceProvider
{

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    //protected $defer = true;

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {

        $this->app->bind(
            'App\Repositories\GalleryRepositoryInterface',
            'App\Repositories\GalleryEloquentRepository'
        );
    }
}

//4. At the controller you can do this

<?php namespace App\Http\Controllers;

use \View;
use App\Repositories\GalleryRepositoryInterface;

class GalleryController extends Controller {

    public function __construct(GalleryRepositoryInterface $galleryInterface)
    {
        $this->galleryInterface = $galleryInterface;

    }


    public function index()
    {
        $gallery = $this->galleryInterface->all();

        return $gallery ? Response::json($gallery->toArray()) : Response::json($gallery,500);
    }

}
like image 137
Emeka Mbah Avatar answered Oct 12 '22 23:10

Emeka Mbah