2015-03-26 2 views
6

PHP Collègues:Laravel Cache :: Meilleures pratiques

Cette question concerne les meilleures pratiques pour utiliser Laravel Cache.

L'objectif principal est de réduire le nombre d'accès à la base de données pour toutes les raisons liées aux performances habituelles. L'application est un site de nouvelles intensif en lecture avec peut-être une douzaine de contrôleurs au maximum, principalement des ressources.

Existe-t-il des meilleures pratiques documentées pour la conception de l'application? Il me semble évident que puisque Cache :: est une instruction d'une ligne, il est facile de la déposer dans les contrôleurs - soit retourner les données en cache ou appeler le modèle et mettre en cache les résultats. Et invalider le cache (peut-être avec un rechargement rapide) lorsque les requêtes mettent à jour le modèle. Mais est-ce une bonne pratique?

Voici un premier aperçu de le faire dans le contrôleur

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

J'ai entendu la suggestion que vous pouvez utiliser des filtres Laravel Route pour mettre en cache les réponses, mais je ne peux pas tout à fait obtenir ma tête l'idée.

Pensées? Les références? Exemples?

Merci à tous, Ray

+0

La gestion du cache est difficile, tout dépend de ce que vous mettez en cache. Si vous présentez une valeur approximée, vous ne vous souciez pas si les données sous-jacentes sont obsolètes, inversement, si vous mettez en cache quelque chose comme les ALC, il peut toujours être correct (puis vidé lorsque le magasin de données sous-jacent est mis à jour) . – Matthew

+0

Vous devriez découpler votre logique dans votre contrôleur, par exemple vous pouvez passer le cache d'indice de type à votre constructeur de contrôleur, je suggère également que vous créez des dépôts pour votre mise en cache, afin que vous puissiez tirer parti des capacités de cache. – Darick

Répondre

12

Beaucoup de gens le font différemment, mais quand les meilleures pratiques est une préoccupation que je crois que le meilleur endroit pour faire la mise en cache est dans votre référentiel.

Votre contrôleur ne devrait pas en savoir trop sur la source de données que je veux dire si elle provient du cache ou provient de la base de données. La mise en mémoire cache dans le contrôleur ne prend pas en charge l'approche DRY (Do not Repeat Yourself), car vous vous retrouvez à dupliquer votre code dans plusieurs contrôleurs et méthodes, ce qui rend les scripts difficiles à maintenir.

Donc, pour moi, c'est comment je roule dans Laravel 5 pas si différents si utilisent Laravel 4:

// 1. Créer GalleryEloquentRepository.php dans 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. Créer GalleryRepositoryInterface.php dans App/Repositories

<?php namespace App\Repositories; 

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

    public function find($id); 

    public function all(); 
} 

// 3. Créer RepositoryServiceProvider.php dans 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. Au niveau du contrôleur, vous pouvez le faire

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

} 
+1

Bonne réponse, @Digilimit. –

+0

Donc, pas dans les modèles? – rjksn

+0

Le modèle est également un bon endroit, mais n'allons pas surpasser le modèle avec beaucoup de code. – Digitlimit