Sling Academy
Home/PHP/How to store and read data from cache in Laravel

How to store and read data from cache in Laravel

Last updated: January 16, 2024

Introduction

Laravel provides a unified API for various caching systems. It supports popular caching backends like Memcached and Redis out of the box. Laravel uses the file cache driver by default, which stores cached objects in the file system. For larger applications, it is recommended to use an in-memory cache such as Memcached or Redis as they provide better performance.

Setup & Configuration

The first step is to configure the cache settings for your application, which can be done in the ‘config/cache.php’ file. You can set the default cache driver and configure the stores each driver utilizes.

'default' => env('CACHE_DRIVER', 'file'),

'stores' => [
    'file' => [
        'driver' => 'file',
        'path' => storage_path('framework/cache/data'),
    ],
    // More drivers...
],

Remember to set the .env file with the proper CACHE_DRIVER.

Storing Items in Cache

To store items in the cache, you can use the Cache::put method. You need to specify the key and value, and optionally the number of minutes until the item should be removed.

use Illuminate\Support\Facades\Cache; 

// Store an item for 10 minutes 
Cache::put('key', 'value', 10);

Checking For Item Existence

To determine if an item is in the cache, you can use the Cache::has method, which will return true or false:

if (Cache::has('key')) { 
   // The item exists in the cache... 
}

Reading Items From Cache

To retrieve an item from the cache, you can use the Cache::get method:

$value = Cache::get('key');

If the item does not exist in the cache, get will return null. You can also pass a second argument to specify a default value:

$value = Cache::get('key', 'default');

Incrementing / Decrementing Values

Laravel also provides methods for incrementing and decrementing integer values in the cache:

Cache::increment('key'); 
Cache::decrement('key');

Storing Items Indefinitely

Sometimes, you may wish to store an item in the cache indefinitely:

Cache::forever('key', 'value');

Retrieving & Storing

Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn’t exist.

$value = Cache::remember('key', $minutes, function () { 
   return DB::table(...)->get(); 
});

You may even store items forever:

$value = Cache::rememberForever('key', function () { 
   return DB::table(...)->get(); 
});

Deleting Items From the Cache

To remove an item from the cache, use the Cache::forget method:

Cache::forget('key');

Finally, you can flush the entire cache using the Cache::flush method, which will remove all items:

Cache::flush();

Database Cache Locks

Starting from Laravel 5.6, you can acquire locks on cache operations which can be useful to prevent race conditions:

if (Cache::lock('foo', 10)->get()) { 
  // Lock acquired for 10 seconds... 
  Cache::lock('foo')->release(); 
}

In this case, the second parameter of the get method is the number of seconds the lock should be held.

Tags & Tagged Cache

For the store supports tags, you can tag related items in the cache and then flush all caches that have assigned a given tag. This approach is particularly useful for categorizing related items.

Cache::tags(['people', 'artists'])->put('John', $john, $minutes); Cache::tags(['people'])->flush();

Advanced Example: Repository Pattern


Implementing the Repository Pattern in Laravel is a great way to abstract the caching layer and other data access logic. This pattern involves creating repository classes that centralize the logic for accessing data sources (like databases), and can be particularly useful for caching. Here’s an example of how you might implement this pattern:

Step 1: Create the Repository Interface

First, define an interface for your repository. This will ensure that any concrete repository classes implement specific methods.

namespace App\Repositories;

interface ProductRepositoryInterface
{
    public function getAll();

    public function findById($id);

    // Other necessary methods...
}

Step 2: Create the Concrete Repository

Next, create a concrete class that implements this interface. This is where you implement the caching logic.

namespace App\Repositories;

use App\Models\Product;
use Illuminate\Support\Facades\Cache;

class ProductRepository implements ProductRepositoryInterface
{
    protected $model;

    public function __construct(Product $product)
    {
        $this->model = $product;
    }

    public function getAll()
    {
        $cacheKey = 'products_all';
        return Cache::remember($cacheKey, 3600, function () {
            return $this->model->all();
        });
    }

    public function findById($id)
    {
        $cacheKey = 'product_'.$id;
        return Cache::remember($cacheKey, 3600, function () use ($id) {
            return $this->model->find($id);
        });
    }

    // Implement other methods...
}

Step 3: Bind the Interface to the Implementation

In a service provider (like AppServiceProvider), bind the interface to the concrete class.

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Repositories\ProductRepositoryInterface;
use App\Repositories\ProductRepository;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(ProductRepositoryInterface::class, ProductRepository::class);
    }

    // ...
}

Step 4: Use the Repository in Controllers

Finally, use the repository in your controllers by type-hinting the interface in the constructor.

namespace App\Http\Controllers;

use App\Repositories\ProductRepositoryInterface;

class ProductController extends Controller
{
    protected $productRepository;

    public function __construct(ProductRepositoryInterface $productRepository)
    {
        $this->productRepository = $productRepository;
    }

    public function index()
    {
        $products = $this->productRepository->getAll();
        return view('products.index', compact('products'));
    }

    // Other methods...
}

Explanation

  • Repository Interface: This defines the contract for the repository, ensuring consistency and predictability.
  • Concrete Repository: Implements the interface, encapsulating the data access logic and caching.
  • Service Provider: Binds the interface to a concrete implementation, allowing Laravel’s dependency injection to resolve the correct instance.
  • Controller: Uses the repository interface, making it easy to switch implementations or mock the repository in tests.

This pattern helps in keeping controllers slim and adhering to the Single Responsibility Principle. It also makes your application more maintainable and testable.

Conclusion

Caching is essential for optimizing performance in your Laravel applications. By effectively utilizing Laravel’s caching features, you can significantly reduce database load and improve application responsiveness.

Next Article: Collections in Laravel: A Deep Dive with Examples

Previous Article: Using laravel-websocket in Laravel to Build Real-Time Apps

Series: Laravel & Eloquent Tutorials

PHP

You May Also Like

  • Pandas DataFrame.value_counts() method: Explained with examples
  • Constructor Property Promotion in PHP: Tutorial & Examples
  • Understanding mixed types in PHP (5 examples)
  • Union Types in PHP: A practical guide (5 examples)
  • PHP: How to implement type checking in a function (PHP 8+)
  • Symfony + Doctrine: Implementing cursor-based pagination
  • Laravel + Eloquent: How to Group Data by Multiple Columns
  • PHP: How to convert CSV data to HTML tables
  • Using ‘never’ return type in PHP (PHP 8.1+)
  • Nullable (Optional) Types in PHP: A practical guide (5 examples)
  • Explore Attributes (Annotations) in Modern PHP (5 examples)
  • An introduction to WeakMap in PHP (6 examples)
  • Type Declarations for Class Properties in PHP (5 examples)
  • Static Return Type in PHP: Explained with examples
  • PHP: Using DocBlock comments to annotate variables
  • PHP: How to ping a server/website and get the response time
  • PHP: 3 Ways to Get City/Country from IP Address
  • PHP: How to find the mode(s) of an array (4 examples)
  • PHP: Calculate standard deviation & variance of an array