Hi, and welcome to another blog post related to Symfony ๐
Letโs start with a fact :
In a big project, there is often some data that is not frequently changing and required to be loaded after being logged in. When the number of users and the number of data increases, this may cause some performance issues and might be annoying for end users.
In these situations, many paths of optimizations are available:
Optimizing application code.
Optimizing database (indexes, โฆ)
โฆ
Caching which we are going to focus on in this post.
There are many ways of caching:
Web caching:
It consists of caching a response for a defined amount of time, which can be done on the client-side(i.e: browser cache) or in the server-side. [Details]
Data caching:
Data caching can avoid unnecessary repeated trips back to the database, it can be handy if the data is not changing frequently and the application is querying for the same data all the time. Some databases like MySQL and MariaDB have caching solutions that help speed up the process.
Application caching:
This type of caching is useful when your program uses a method that is very slow, application caching consists of storing the result of the slow method somewhere and use it for the upcoming requests which will speed up the processing time significantly.
Key-Value data caching:
This way of caching relies on the same concept as application cache but it comes with the advantage of not losing data upon reboots or server failure.
Among the popular key-value data caching databases, there is Redis and Memcached which are both in-memory databases.
As you have noticed in the title of this post, we are going to interact with Redis using a Symfony 3.4 application, so letโs get started ๐.
Project setup
Create a blank Symfony project :
composer create-project symfony/framework-standard-edition RedisSymfony3 "3.4.*"
Adding redis-bundle
composer require snc/redis-bundle
After installing the bundle we need to enable it by adding the bundle class in the bundles array in AppKernel
class:
$bundles = [
....
new Snc\RedisBundle\SncRedisBundle(),
];
Enabling the bundle is not enough, a little configuration is required in order to communicate with Redis from our application.
For that we need to add below code in our app/config/config.yml file :
snc_redis:
clients:
default:
type: phpredis
alias: default
dsn: redis://hostname # (*)
logging: '%kernel.debug%'
(*): The hostname must be accessible within the network.
We are all set now, we can fetch and store data in Redis.
Communicating with Redis
By installing redis-bundle, we get access to a Redis client class Snc\RedisBundle\Client\Phpredis\Client
which contains various methods (get, set, flush, โฆ).
Fetching all Redis keys.
In order to get all the keys stored in Redis, we use the keys method with * as an argument.
Sample Code :
<?php
namespace AppBundle\Controller;
use Snc\RedisBundle\Client\Phpredis\Client;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DefaultController extends Controller
{
/** @var Client */
private $redisClient;
public function __construct(Client $client)
{
$this->redisClient = $client;
}
/**
* @Route("/keys", name="keys")
*/
public function indexAction()
{
$redisKeys = $this->redisClient->keys('*');
return $this->json(['keys' => $redisKeys]);
}
}
Adding key/value pairs in Redis.
For setting a new key/value pair, there is the set method :
set(key, value)
Sample Code :
<?php
namespace AppBundle\Controller;
use Snc\RedisBundle\Client\Phpredis\Client;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DefaultController extends Controller
{
/** @var Client */
private $redisClient;
public function __construct(Client $client)
{
$this->redisClient = $client;
}
/**
* @param $key
* @param $value
*
* @Route("/create/{key}/{value}", name="create_key", methods={"GET"})
* @return JsonResponse
*/
public function createKeyAction($key, $value) {
$this->redisClient->set($key, $value);
return $this->json([
"status" => Response::HTTP_OK
]);
}
}
Deleting a key/value pair from Redis.
For deleting a key, there is a delete method that accepts the key as the argument.
Sample code :
<?php
namespace AppBundle\Controller;
use Snc\RedisBundle\Client\Phpredis\Client;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DefaultController extends Controller
{
/** @var Client */
private $redisClient;
public function __construct(Client $client)
{
$this->redisClient = $client;
}
/**
* @param $key
* @Route("/delete/{key}", name="delete_key", methods={"GET"})
*
* @return JsonResponse
*/
public function deleteKeyAction($key) {
$this->redisClient->delete($key);
return $this->json([
"status" => Response::HTTP_OK
]);
}
}
There is also the possibility to remove a set of keys by a pattern like this :
$this->redisClient->delete($this->redisClient->keys($key."*"));
Sample code :
<?php
namespace AppBundle\Controller;
use Snc\RedisBundle\Client\Phpredis\Client;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DefaultController extends Controller
{
/** @var Client */
private $redisClient;
public function __construct(Client $client)
{
$this->redisClient = $client;
}
/**
* @param $key
* @Route("/delete/like/{key}", name="delete_like_key", methods={"GET"})
*
* @return JsonResponse
*/
public function deleteKeyLikeAction($key) {
$this->redisClient->delete($this->redisClient->keys($key."*"));
return $this->json([
"status" => Response::HTTP_OK
]);
}
}
That was it for this post, the full code is available here.
Cheers ๐
Top comments (1)
You really should mention symfony version (3.4) in the first paragraph