2015-03-26 26 views
6

PHP Colleghi:Laravel Cache :: Best practice

Questa domanda si riferisce alle migliori pratiche per l'utilizzo di Laravel Cache.

L'obiettivo principale è ridurre il numero di accessi al database per tutti i soliti motivi relativi alle prestazioni dello . L'applicazione è un sito di notizie ad alta intensità di lettura con forse una dozzina di controller al massimo, principalmente di tipo risorsa.

Esistono buone pratiche documentate per la progettazione dell'applicazione? Mi sembra ovvio, , che poiché Cache :: è un'istruzione a riga singola, è facile rilasciarlo nei controller - restituire i dati memorizzati nella cache o chiamare il modello e memorizzare i risultati nella cache. E invalida la cache (magari con una ricarica avida) quando le richieste aggiornano il modello. Ma è una buona pratica?

Ecco un primo sguardo a fare questo nel 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); 
} 

Ho sentito il suggerimento che si potrebbe usare i filtri laravel itinerario di memorizzare nella cache le risposte, ma non posso abbastanza ottenere la mia testa intorno l'idea.

Pensieri? Riferimenti? Esempi?

Grazie a tutti, Ray

+0

è difficile, tutto dipende da quello che stai caching. Se stai presentando un valore approssimato potresti non interessarti se i dati sottostanti sono un po 'obsoleti, viceversa se stai memorizzando nella cache qualcosa come ALC potrebbe sempre essere corretto (e poi svuotato quando l'archivio dati sottostante viene aggiornato) . – Matthew

+0

Dovresti disaccoppiare la logica nel controller, ad esempio potresti passare la cache del tipo di suggerimento al costruttore del controller, inoltre ti suggerisco di creare repository per la memorizzazione nella cache, in modo da sfruttare le capacità di caching di laravel. – Darick

risposta

12

Molte persone fanno questo in modo diverso, ma quando le best practice è una preoccupazione credo che il posto migliore per fare il caching è nel vostro repository.

Il controller non dovrebbe sapere troppo sulla fonte di dati, voglio dire se proviene dalla cache o proviene dal database.

Il caching nel controller non supporta l'approccio DRY (Do not Repeat Yourself), perché vi trovate a duplicare il codice in diversi controller e metodi, rendendo così gli script difficili da mantenere.

Quindi per me questo è come mi rotolo nel laravel 5 non in modo diverso se si utilizza laravel 4:

// 1. Crea GalleryEloquentRepository.php in App/Repository

<?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. Crea GalleryRepositoryInterface.php in App/Repository

<?php namespace App\Repositories; 

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

    public function find($id); 

    public function all(); 
} 

// 3. Creare RepositoryServiceProvider.php in App/Provider

<?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. Presso il controller si può fare questa gestione della cache

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

Buona risposta, @Digilimit. –

+0

Quindi, non nei modelli? – rjksn

+0

Anche il modello è un buon posto, ma non esageriamo con il modello della folla con tanto codice. – Digitlimit