Redis + Laravel: Storing and retrieving objects

Is well know the usage of Redis as Cache. Several developers use it as a modern alternative to Memcached but still using Redis the Memcached way. Truth is that Redis has a lot of features besides only storing key-value pairs like Memcached.

One of this features is the support of several data types:

  • Strings. (the only data type supported by Memcached)
  • Lists. (list of strings, comparable with an array).
  • Sets. (Same as List but with out order)
  • Hashes. (maps between string fields and string values).

Hashes are the best way to store objects (Or string key arrays).  Lets see how to do this using Laravel.

Laravel has a good implementation of Redis as part of the core, we will only need to install a couple of things in order to use it. The documentation is pretty clear about how to do it. You can take a look if you want.

Redis has a few commands to handle Hashes. You can see a full list here.

First, in order to keep the things in order, lets create a class named Client that will represent a client of an imaginary company.

<?php //app/Client.php
namespace App;
use Illuminate\Support\Facades\Redis;
class Client
{
    public function __construct($id, $name, $email, $address)
    {
       $this->id      = $id;
       $this->name    = $name;
       $this->email   = $email;
       $this->address = $address
    }
}

This class will force that in the declaration of a new instance we provide all the client data.

In order to Store a new Hash we will implement a method called store() where will use the Redis command HMSET in order to store a new objet with a key:

//app/Client.php
...
public function store()
{
    Redis::hmset('client:' . $this->id, [
        'id'      => $this->id,
        'name'    => $this->name,
        'email'   => $this->email,
        'address' => $this->address
    ]);
}
...

This simple method stores an instance of the class Client in Redis. For example if the id of the user is 1 the key of the hash will be ‘client:1’.

In order to Retrieve a particular instance by ID will be need to implement a class method named find, and we’ll use the the Redis command HGETALL in order to return a new instance of the class.

//app/Client.php
...
public static function find($id)
{
    $key = 'client:' . $id;
    $stored = Redis::hgetall($key);
    if (!empty($stored)) {
        return new Client($stored['id'], $stored['name'], $stored['email'], $stored['address']);
    }
    return false;
}
...

The method Redis::hgetAll($key) will return an associative array with all the hash data. In case we only need to get the “email” of the user 1 we need to use HGET”

$client = new Client(1, 'Homer Simpson', '[email protected]','742 Evergreen Terrace');
$email = Redis::hget('client:1', email);

echo $email;
//will print: "[email protected]"

Redis has a command KEYS that retrieves all keys for a given pattern, and we will use it in order to retrieve all Clients objects.

//app/Client.php
...
public static function getAll()
{
    $keys = Redis::keys('client:*');
    $clients = [];
    foreach ($keys as $key) {
        $stored = Redis::hgetall($key);
        $client = new Client($stored['id'], $stored['name'], $stored['email'], $stored['address']);
        $clients[] = $client;
    }
    return $clients;
}
...

This way we return all Clients stored in Redis. We do this because Redis has no a way to retrieve all hashes for a specific key pattern so we must implement this kind of method.

Laravel implements all Redis commands as dynamic method so every Redis command is a static method of the class Redis.

Thats it, now you are ready to implement your Redis models in your Laravel application.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.