Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
350 views
in Technique[技术] by (71.8m points)

php - 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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 AppRepositories;

use AppModelsGallery;
use Cache;

/**
 * Class GalleryEloquentRepository
 * @package AppRepositories
 */
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 AppRepositories;

/**
 * Interface GalleryRepositoryInterface
 * @package AppRepositories
 */
interface GalleryRepositoryInterface
{

    public function find($id);

    public function all();
}

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

<?php namespace AppProviders;

use IlluminateSupportServiceProvider;

/**
 * Class RepositoryServiceProvider
 * @package AppProviders
 */
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(
            'AppRepositoriesGalleryRepositoryInterface',
            'AppRepositoriesGalleryEloquentRepository'
        );
    }
}

//4. At the controller you can do this

<?php namespace AppHttpControllers;

use View;
use AppRepositoriesGalleryRepositoryInterface;

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

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...