Cachning är viktigt för att uppnå hög prestanda och skalbarhet. Att implementera den korrekta cachningsstrategin direkt från utvecklingsfasen är avgörande för att undvika tröga API:er och höga sidladdningstider. Laravel är ett av de mest populära PHP-ramverken, så att implementera den optimala Laravel-cachningsstrategin är oumbärligt för en bättre användarupplevelse och bättre affärseffekt.

I den här artikeln kommer vi att undersöka strategier för att implementera och manipulera cachning i Laravel. Du kommer lära dig om hur Laravel-cachning fungerar, flera Laravel-cachningsförfrågningar, , och hur du kan hantera cachning på Laravel-appar.

Du får ut mer av den här artikeln om du redan har en grundläggande kunskap av följande:

Nu börjar vi!

Kolla in vår videoguide om Laravel Cache

Varför är cachning viktigt?

I och med den senaste boomen för internetföretag har olika företag statistik som visar hur webbplatsens laddningstid och låga prestanda kraftigt kan påverka SEO, användarengagemang, och konverteringsfrekvens utan cachning. Och det börjar med en utmärkt cachningsstrategi.

En onlinestudie fann att, ”1 sekund extra laddningstid skulle kosta Amazon $1,6 miljarder i försäljning varje år”.

En annan Google-studie rapporterade, ”Vår forskning visar att om sökresultaten saktas ner med ens en bråkdel av en sekund, söker folk mindre (allvarligt: en 400ms fördröjning leder till en 0,44% minskning i sökvolym). Och denna otålighet är inte bara begränsad till sökning: fyra av fem internetanvändare kommer att lämna videon om det dröjer innan den startar”.

En mindre försening i din webbsidas laddningstid kan resultera i en massiv inverkan på användarupplevelsen, och förlust av pengar.

Vad är Laravel-cachning?

Laravel ger en robust och lättanvänd implementering av cachning och olika cachnings-backender. Med Laravel-cachning kan du effektivt växla mellan många cachningsmotorer utan att behöva skriva någon kod.

Du hittar konfigurationen av Laravel-cacheminnet i config/cache.php-mappen, även om du nog bara behöver .env-filen för att växla mellan olika cachnings-backender.

Laravel-cachning ger dig också många praktiska metoder som du kan använda för olika cachningsstrategier.

Laravels cachedriver och jämförelser

Laravels cache ger dig en bra cachnings-backend och driver. Beroende på just dina behov kan du växla mellan dem för att förbättra din applikationsprestanda och laddningstid.

Med det sagt ger Laravel-cachningen dig också ett smidigt sätt att skapa en anpassad backend och använda den med Laravel-cachningen, men bara om listan nedan inte passar dina behov.

Vi pratar om listan över alla backender som tillhandahålls av Laravel-cachningen nedan.

1. Fil

Fil-drivern är standard-backenden som används av Laravels cache när ingen driver angetts i .env-filen.

Fil-backenden är utformad för att lagra cachade data i en krypterad fil under storage/framework/. Laravel skapar en krypterad fil med data och cachenyckeln när nya data cachelagras. Samma sak händer när användaren försöker hämta innehållet. Laravel-cachningen söker igenom mappen för den angivna nyckeln och, om den hittas, returnerar innehållet.

Även om Fil-backenden fungerar felfritt och sparar tid på att installera och konfigurera externa drivers, kan den också vara perfekt för utveckling. Det är snabbare än att komma åt data från databasservern direkt.

För att använda Fil-drivern, lägg till följande kod till din .env-fil:

CACHE_DRIVER=file

2. Array

Array-drivern är en perfekt cachningsbackend för att köra automatiserade tester och konfigureras enkelt med Github Actions, Jenkins, etc.

Array-backenden lagrar cachade data i en array i PHP och kräver inte att du installerar eller konfigurerar någon driver. Det fungerar perfekt för automatiserade tester, och är lite snabbare än File-cachen.

För att använda array-drivern, lägg till följande kod till din .env-fil:

CACHE_DRIVER=array

3. Databas

När du använder databas-drivern, lagras data i den aktuella PHP-processens minne. Därför måste du skapa en databastabell för att lagra cachade data. Dessutom förbättrar databas-cachningen skalbarheten genom att distribuera förfrågnings-arbetsbelastningen från backenden till flera frontender.

Du kan köra det här Artisan-kommandot — php artisan cache:table — för att automatiskt generera databasschemat som databasdrivern behöver.

Databastabell-drivern används främst i situationer då du installerar programvara på din hostingplattform.

Till exempel, låt oss säga att du använder ett gratis webbhotell med begränsade alternativ. För det skulle vi föreslå att du håller dig vid fil-drivern eftersom databas-drivern i de flesta fall är den svagaste punkten i din applikation, och att försöka driva in mer data i den flaskhalsen är inte en bra idé.

För att använda databas-drivern, lägg till följande kod till din .env-fil:

CACHE_DRIVER=database

4. Redis

Redis-drivern använder den minnesbaserade cachningstekniken som kallas Redis. Även om den är snabb jämfört med andra cachedrivers som diskuterats ovan kräver den att du installerar och konfigurerar extern teknik.

För att använda redis-drivern, lägg till följande kod till din .env-fil:

CACHE_DRIVER=redis

5. Memcached

Memcached är känt som den mest populära bland minnesbaserad cachelagring. Om du inte har något emot lite extra serverunderhåll (att behöva installera och underhålla ytterligare tjänster), är den minnesbaserade cachedrivern Memcached ett bra alternativ.

Att använda memcached-drivern kräver att Memcached PECL-paketet installeras.

För att använda memcached driver, lägg till följande kod till din .env-fil.

CACHE_DRIVER=memcached 

Den bästa cachedrivern att använda och dess prestanda beror på ditt projekts användningsfall och mängden data som ska hämtas.

Laravel-cachningens användning och metoder

Laravel-cachningen ger dig många värdefulla metoder för att implementera många cachningsstrategier.

Nedan listar vi och förklarar de olika metoderna (kategoriserade enligt användningsfall):

  1. put()
  2. get()
  3. many()
  4. putMany()
  5. increment()
  6. decrement()
  7. forever()
  8. forget()
  9. flush()
  10. remember()
  11. rememberForever()

Att lagra cache

Lagring av nya data i cacheminnet är mycket enkelt och använder olika metoder, var och en med flera användningsfall.

1. Cache::put()

Denna metod accepterar tre key-parametrar, duration och de data som ska cachas.

Låt oss ta en titt på hur man använder Cache::put():

Cache::put(key, data, duration)

$post = Post::find(1);

Cache::put('post_1', $post, 20);

Koden ovan kommer att cachelagra inlägget med dess unika key i 20 sekunder.

2. Cache::putMany()

Denna metod lagrar en array data i cacheminnet samtidigt med samma varaktighet. Den accepterar två parametrar som är data och seconds.

Låt oss ta en titt på hur man använder Cache::putMany():

Cache::putMany(data, duration) // syntax

$posts = Post::all();

Cache::putMany($posts, 20);
3. Cache::remember()

Denna metod är ett till utmärkt sätt att implementera cacheminnets Aside-strategi. Cache::remember()-metoden accepterar tre parametrar, en key, seconds, och closure används för att hämta data från databasen om den inte hittas.

Låt oss ta en titt på hur man använder Cache::remember():

Cache::remember(key, duration, closure) // syntax

Cache::remember('posts', 20, function(){
  return Post::all();
});

Laravel-cachningen har också Cache::rememberForever()-metoden, som inte accepterar seconds-parametern och lagrar data för alltid.

4. Cache::forever()

Denna metod lagrar data i cacheservern för alltid utan att ange någon varaktighet. Du kan implementera den med följande kod:

Cache::forever(key, data)

$post = Post::find(1);

Cache::forever('post_1', $post);

Hämta cachedata

Metoderna i denna kategori hämtar data från cacheminnet. Några av dessa metoder kan uppträda olika beroende på om data hittas eller inte.

1. Cache::get()

Denna metod hämtar data från cacheservern med en specifik nyckel. Du kan hämta ett objekt med hjälp av koden nedan:

Cache::get(key) // syntax

$posts = Cache::get('posts');
2. Cache::many()

Denna metod liknar Cache::putMany(). Den används för att hämta en array med cachelagrade data på en gång med hjälp av en array av cachade nycklar. Du kan hämta en array cache med följande kod:

Cache::many(keys) // syntax

const $keys = [
  'posts',
  'post_1',
  'post_2'
];

$posts = Cache::many($keys);
3. Cache::remember()

Du kan också använda den här metoden för att hämta cachelagrade data genom att kontrollera cacheservern med hjälp av den tillhandahållna nyckeln. Om data lagras i cacheminnet kommer det att hämta dem. Annars kommer det att hämta data från databasservern och cacha dem. Denna metod är samma som Cache::rememberForever()-metoden med bara en extra seconds-parameter i Cache::remember()-metoden.

Ta bort objekt från cacheminnet

Metoderna under denna kategori används för att ta bort objekt från cacheminnet, grupperade efter funktionalitet.

1. Cache::forget()

Denna metod tar bort ett enda objekt från cacheminnet med en angiven nyckelparameter:

Cache::forget('key');
2. Cache::flush()

Denna metod rensar alla cachemotorer. Den tar bort alla objekt som lagrats någonstans i cacheminnet:

Cache::flush();

Öka eller minska cachevärdena

Du kan justera värdena för ett heltalsvärde som lagrats i cachen med hjälp av öknings- och minskningsmetoder, respektive:

Cache::increment('key');

Cache::increment('key', $amount);

Cache::decrement('key');

Cache::decrement('key', $amount);

Laravel-cachningen har många bra metoder som vi inte har diskuterat ovan, men ovanstående metoder är populära. Du kan få en översikt över alla metoder i den officiella dokumentationen för Laravel-cachningen.

Förklaring över cachekommandon

Laravel tillhandahåller kommandon för att göra det enkelt och snabbt att arbeta med Laravel-cachningen. Nedan är listan över alla kommandon och deras funktioner.

Rensa Laravel-cachningen

Detta kommando används för att rensa Laravel-cachningen innan den ens går ut med terminalen/konsolen. Du kan till exempel köra följande kommando:

php artisan cache:clear

Rensa route-cache

Det här kommandot används för att rensa route-cachen i din Laravel-applikation. Kör till exempel följande kommando för att rensa route-cachen:

php artisan config:cache

Rensa kompilerade visningsfiler

Det här kommandot används för att rensa de kompilerade visningsfilerna i din Laravel-applikation. Du kan uppnå det med följande kommando:

php artisan view:clear

Databastabell

När du använder databasdrivern måste du skapa ett databasschema som heter cache för att lagra cachedata. Du kan också använda Artisan-kommandot för att generera en migrering med rätt schema:

php artisan cache:table

Laravel-cachningsstrategier

Beroende på din applikations användningsfall och datastruktur finns det troligtvis flera olika cachningsstrategier tillgängliga för dig. Du kan också skapa en anpassad strategi för att passa dina behov. Nedan går vi igenom listan över populära cachningsstrategier som du kan implementera i ditt Laravel-projekt.

writeThrough

I writeThrough-strategin sitter cacheservern mellan förfrågningarna och databasservern, vilket tar varje write-operation igenom cacheservern innan den går till databasservern. Således liknar cachningsstrategin writeThrough readThrough-strategin.

Du kan implementera denna strategi med Laravel-cachning med följande kod:

public function writeThrough($key, $data, $minutes) {
    $cacheData = Cache::put($key, $data, $minutes)

    // Database Server is called from(after) the Cache Server.
    $this->storeToDB($cachedData)
    return $cacheData
}

private function storeToDB($data){
    Database::create($data)
    return true
}

writeBack (writeBehind)

Denna strategi är ett mer avancerat sätt att genomföra writeThrough-strategin genom att lägga till förseningar för skrivoperationer.

Du kan också kalla detta writeBehind-strategin på grund av tidsfördröjningen som tillämpas på cacheservern innan du skickar data till databasservern.

Du kan implementera denna strategi med Laravel-cachningen med följande kod:

$durationToFlush = 1; // (in minute)
 $tempDataToFlush = [];

  public function writeBack($key, $data, $minutes){
    return $this->writeThrough($key, $data, $minutes);
  }

  public function writeThrough($key, $data, $minutes) {
      $cacheData = Cache::put($key, $data, $minutes);
      $this->storeForUpdates($cacheData);
      return $cacheData;
  }

// Stores new data to temp Array for updating
  private function storeForUpdates($data){
    $tempData = {};
    $tempData['duration'] = this.getMinutesInMilli();
    $tempData['data'] = data;
    array_push($tempDataToFlush, data);
  }

// Converts minutes to millisecond
private function getMinutesInMilli(){
  $currentDate = now();
  $futureDate = Carbon(Carbon::now()->timestamp + $this->durationToFlush * 60000)
  return $futureDate->timestamp
}

// Calls to update the Database Server.
public function updateDatabaseServer(){
  if($this->tempDataToFlush){
    foreach($this->tempDataToFlush as $index => $obj){
      if($obj->duration timestamp){
        if(Database::create($obj->data)){
            array_splice($this->tempDataToFlush, $index, 1);
        }
      }
    }
  }
}

writeBack-metoden anropar writeThrough-metoden, som lagrar data på cacheservern och en tillfällig array som senare ska skickas till databasservern med hjälp av updateDatabaseServer-metoden. Du kan ställa in ett CronJob till att uppdatera databasservern var femte minut.

writeAround

Denna strategi låter alla write-operationer gå direkt till databasservern utan att uppdatera cacheservern – endast under read-operationer uppdateras cacheservern.

Om en användare vill skapa en ny Article, lagras den direkt på databasservern. När användaren vill läsa artikeln för första gången hämtas Article från databasservern och uppdaterar cacheservern för efterföljande förfrågningar.

Du kan implementera denna strategi med Laravel-cachningen med följande kod:

public function writeAround($data) {
    $storedData = Database::create($data);
    return $storedData;
}

public function readOperation($key, $minutes){
    $cacheData = Cache::remember($key, $minutes, function() {
      return Article::all();
    })
    return $cacheData;
}

Cache Aside (latladdning)

Databasen sitter åt sidan i denna s.k. Aside-strategi, och programmet begär data från cacheservern först. Om det sedan finns en träff (found) returneras data till klienten. Om det däremot finns en miss (not found), begär databasservern dessa data och uppdaterar cacheservern för efterföljande förfrågningar.

Du kan implementera denna strategi med Laravel-cachningen med följande kod:

public function lazyLoadingStrategy($key, $minutes, $callback) {
  if (Cache::has($key)) {
      $data = Cache::get($key);
      return $data;
  } else {
      // Database Server is called outside the Cache Server.
      $data = $callback();
      Cache::set($key, $data, $minutes);
      return $data;
  }
}

Koden ovan visar implementeringen av Aside-strategin, vilket motsvarar implementeringen av Cache::remember-metoden.

Read Through

Denna strategi är raka motsatsen till Cache Aside. I den här strategin sitter cacheservern mellan klientförfrågan och databasservern.

Förfrågan går direkt till cacheservern, och cacheservern ansvarar för att hämta data från databasservern om de inte finns i cacheservern.

Du kan implementera denna strategi med Laravel-cachningen med följande kod:

public function readThrough($key, $minutes) {
      $data = Cache::find($key, $minutes);
      return $data;
}

private function find($key, $minutes){
    if(Cache::has($key);){
      return Cache::get($key);
    }

    // Database Server is called from the Cache Server.
    $DBdata = Database::find($key);
    Cache:put($key, $DBdata, $minutes);
    return $DBdata;
}

Där har du allt! Vi har nu diskuterat några populära cachningsstrategier för din nästa Laravel-applikation. Kom ihåg att du också kan använda en anpassad cachningsstrategi som bättre passar dina projektbehov.

Cachning av UI-delen av en Laravel-app

Cachning av UI-delen av vår Laravel-app är ett begrepp som kallas Full Page Cache (FPC). Termen handlar om processen att cacha HTML-svaret från en applikation.

Det är utmärkt för applikationer där dynamiska HTML-data inte ändras ofta. Du kan cacha HTML-svaret för snabbare övergripande svar och rendering av HTML.

Vi kan implementera FPC med följande rader kod:

class ArticlesController extends Controller {
    public function index() {
        if ( Cache::has('articles_index') ) {
            return Cache::get('articles_index');
        } else {
            $news = News::all();
            $cachedData = view('articles.index')->with('articles', $news)->render();
            Cache::put('articles_index', $cachedData);                                         
            return $cachedData;           
        }  
    }
}

Vid första anblicken kanske du har märkt att vi kontrollerar om articles_index-sidan redan finns i vår cacheserver. Sedan returnerar vi sidan genom att rendera den med Laravels view() och render()-metoder.

Annars renderar vi sidan och lagrar utmatningen i vår cacheserver för efterföljande förfrågningar innan den returnerar den renderade sidan till webbläsaren.

Bygg en Laravel-app

Nu ska vi tillämpa vad vi har lärt oss hittills genom att skapa ett nytt Laravel-projekt och implementera Laravel-cachningen.

Om du inte har använt Laravel kan du läsa igenom vad Laravel är och kika på vår lista över utmärkta Laravel-guider för att komma i gång.

Att installera Laravel

Först ska vi skapa en ny Laravel-instans med kommandot nedan. Du kan titta i den officiella dokumentationen för mer information.

Öppna din konsol och navigera till den plats där du lagrar dina PHP-projekt innan du kör kommandona nedan. Se till att ha Composer installerat och korrekt konfigurerat.

composer create-project laravel/laravel fast-blog-app

// Change directory to current Laravel installation
cd fast-blog-app

// Start Laravel development server.
php artisan serve

Konfigurera och seeda databasen

Därefter kommer vi att ställa in vår databas, skapa en ny Article-modell och seeda 500 falska datapunkter för testning.

Öppna din databasklient och skapa en ny databas. Vi gör detsamma med namnet fast_blog_app_db och fyller sedan i vår .env-fil med databasuppgifter:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=fast_blog_app_db
DB_USERNAME=//DB USERNAME HERE
DB_PASSWORD=//DB PASSWORD HERE

Därefter kör vi följande kommando för att skapa migreringen och Article-modellen samtidigt:

php artisan make:model Article -m

Öppna den nyskapade migreringen i database/migrations/xxx-create-articles-xxx.php och klistra in följande kod:

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

Kör sedan kommandot nedan för att skapa en ny seeder:

php artisan make:seeder ArticleSeeder

Öppna den nyskapade seeder-filen som finns i database/seeders/ArticleSeeder.php och klistra in följande kod:

<?php
namespace Database\Seeders;
use App\Models\Article;
use Illuminate\Database\Seeder;
class ArticleSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Article::factory()->count(500)->create();
    }
}

Öppna Databaseeder.php-filen i samma katalog och lägg till följande kod:

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(ArticleSeeder::class);
    }
}

Kör sedan kommandot nedan för att skapa en ny fabrik:

php artisan make:factory ArticleFactory

Öppna den nybyggda fabriksfilen i database/factories/ArticleFactory.php och klistra in följande kod:

<?php
namespace Database\Factories;
use App\Models\Article;
use Illuminate\Database\Eloquent\Factories\Factory;
class ArticleFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Article::class;
    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'title' => $this->faker->text(),
            'description' => $this->faker->paragraph(20)
        ];
    }
}

Kör nu kommandot nedan för att migrera vårt nyskapade schema och också seeda våra falska data för testning:

php artisan migrate --seed

Skapa ArticlesController

Därefter kommer vi att skapa vår controller och ställa in våra router för att hantera vår förfrågan och hämta data med hjälp av ovanstående modell.

Kör följande kommando för att skapa en ny ArticlesController inuti app/Http/Controllers-mappen:

php artisan make:controller ArticlesController --resource

Öppna filen och lägg till följande kod i klassen:

// Returns all 500 articles with Caching
public function index() {
  return Cache::remember('articles', 60, function () {
      return Article::all();
  });
}

// Returns all 500 without Caching 
public function allWithoutCache() {
  return Article::all();
}

Därefter öppnar du api.php-filen i routes/-mappen och klistra in i följande kod för att skapa en slutpunkt vi kan anropa för att hämta våra data:

Route::get('/articles', 'ArticlesController@index');

Route::get('/articles/withoutcache', 'ArticlesController@allWithoutcache');

Testa prestandan

Slutligen kommer vi att testa prestandan av vår apps svar med eller utan Laravel-cachningen.

Denna skärmdump visar svarstiden för API:n med cache.

Laravel API svarstid med cache
Laravel API svarstid med cache

Följande skärmdump visar svarstiden för API:n utan cache. Observera att svarstiden har ökat för den cachade instansen med över 5 000%:

Laravel API svarstid utan cache
Laravel API svarstid utan cache

Sammanfattning

Vi har utforskat olika strategier för att implementera och manipulera Laravel-cachning genom att bygga ett nytt projekt, testa dess svarstid och jämföra resultaten.

Du har också lärt dig hur du använder olika Laravel-cachedrivers och metoder. Dessutom implementerade vi olika cachningsstrategier för att hjälpa dig att räkna ut vilken som kan vara rätt för dig.

För mer Laravel, utforska vårt urval av de bästa Laravel-guiderna. Oavsett om du är nybörjare eller en avancerad Laravel-utvecklare finns det något för alla där!

Om du fortfarande har frågor om Laravel-cachning, hör av dig i kommentarfältet.

Solomon Eseme

I am a Software Engineer and Content Creator who is geared toward building high-performing and innovative products following best practices and industry standards. I also love writing about it at Masteringbackend.com. Follow me on Twitter, LinkedIn, and About Me