Laravel Cache Tutorial

laravel cache tutorial

Let’s take a moment to talk about cache. Now when we say cache, we’re not talking about dollar bills, although that’s what it sounds like! Caching is the act of transparently storing data for future use in an attempt to make applications run faster. There are all kinds of ways to cache data, and Laravel makes it easy to do so with just a small number of method calls. Once you have an application up and running, you’ll be ready to tune it to perfection – and handling caching of data is part of that process. Let’s jump in!


Laravel Cache Config

The first thing we can do is to take a look at where the configuration options for caching in Laravel is located. That would be in app/config/cache.php. My configuration file looks like so:

cache.php

First off we can see that there are many options for how you actually want to handle caching. In other words, you can choose which driver to use to handle cache. By default it is set to file, however any of the following are supported: database, apc, memcached, redis, and array.

Next up the path to where the cache data will be stored is specified. Out of the box your cache data will be located at app/storage/cache and this will work fine for most scenarios. The remaining configuration options deal with scenarios where you might be using a database to store the cache data or a memcached option.


Larvel Cache Example

Like many of our other tutorials, a great way to test some functionality in Laravel is to simply whip up a few examples in the home route of your routes.php file.

Cache::put()

The first method we’ll take a look at is the Cache::put() method. It takes three parameters being a key, value, and time in minutes to cache the data. Let’s test it out by giving a key of cachekey, a value of I am in the cache baby!, and a storage time of 1 minute:

Go ahead and load up your home page. Now if you we’re hoping for some really exciting things to happen upon loading that route, I do apologize as you are probably just staring at a blank white page. What this example did do for us though, is create some new cache data in the app/storage/cache folder. In our installation, it created a few subfolders and the resulting data file looks something like 773d6310cb469462e79d0f7ff0a55840 within the app/storage/cache folder. On opening that file, we can see the data that has been cached: 1406759615s:23:”I am in the cache baby!”;

Cache::get()

Ok you’ve stored some data in the cache and you’re ready to retrieve it now instead of bogging down your entire application. How can you fetch that data? It’s quite easy young grasshopper. Just bust out your Cache::get() method and pass it the key of the cache you are trying to retrieve like so:

Load up the home page and like magic, I am in the cache baby! is returned. Awesome! You may have noticed that we only stored our data for 1 minute. That’s not very long. What happens if we try to get data from the cache after it’s gone? Well in that case you can provide a second parameter to the Cache::get() method so that a default value will be provided. For example:

Let’s say you load up the homepage 30 seconds later. Well in that case, your cache data is still there and you find I am in the cache baby!, however if you load the page a few minutes later, the cache will then be expired. In that case our default value will be returned of The cache is empty, so here is something to keep you happy.

Very nice implementation on Laravels part if I do say so myself. If you’ve ever had to build a caching mechanism by hand in any of your non-framework applications, then you can surely appreciate the simplicity of this approach.

Cache::forever()

This method is for storing data into the cache and you just want it to be available for the user, without specifying a time for storage. That might look something like:

Cache::has()

This method is useful for checking to see if the cache has the key you’re looking for. It’s almost like checking a database for an entry before returning it. With this approach, we can check the cache to see if it has what we want, then return it like this:

Cache::forget()

If you do decide to use Cache::forever(), it might be nice to have a way to remove that key from the cache. You can do this with Cache::forget() like so:

So what happens here is, cachekey gets removed from the cache, the if finds that cachekey is no longer there, and we are returned with the data cachekey was forgotten, so this is just random data


Database Caching With Laravel

One of the more useful thing to cache is database requests. Database memory is at a premium when you’re hosting your application with many of the popular web hosting services today. You’ll run out of database processing power before you run out of Web cpu cycles. By caching your database hits, you can conserve some of those resources from your database, not to mention speed up your applications response times. Let’s see how this works.

Model::remember()

When using eloquent to retrieve information from the database, we can make use of a special method called remember() to cache the results of our query for a specified amount of time. Let’s observe the following code:

In the code above we have added a special snippet so that we can view the queries that eloquent creates for us. Anytime a database call is made, since we are listening for illuminate.query, we will see the actual SQL. This is a fantastic feature, and works as a way to profile your application.

Notice we are using the User model to get some data from the database. Notice that remember() method we snuck right in there! This method takes a number value which specifies the number of minutes to cache the result of your database query. In this example we only cache it for a minute, but that is only so we can demonstrate how this works. When we visit the homepage, if the database query is not cached, the SQL will be displayed to the screen. If the query is cached, the data will simply be pulled from cache, and you will not see the query. Notice how this works:


Initial Page Load
laravel cache example


Page Load 30 Seconds Later
laravel database cache


The second time the page loads, we see no SQL displayed. This means that data came right from the cache instead of the database. Epic!


Laravel Cache Output

We now have a rudimentary grasp of how caching works in Laravel. Now that we understand how to cache with key value pairs, as well as caching database hits with remember(), lets see how we can set up full HTML output caching in Laravel.

Laravel Cache Route Filters

By setting up route filters in Laravel, we can accomplish that goal of caching entire HTML output. We can make use of both before and after route filters to handle retrieving or setting the cache. Here is an example of how you would set up a plain Jane route filter right in your routes.php file:

This small snippet first registers a filter by specifying the name of the filter, in this case routename, and then a closure which accepts the parameters of $route, $request, and $response. $route and $request are mandatory for before filters while $route, $request, and $response are required for after filters. Inside the closure, you can do whatever logic you like. In this case we’ll just return I come before the route runs for demonstration purposes. We can trigger that filter by simply adding ->before('routename') to the end of the route we want to apply it to. So in this case when we now visit the homepage route, we’ll simply see I come before the route runs instead of the data returned from the database.

Create Your Own Filter Class

If you would rather create your own class to contain your filter logic, rather than using closures to handle the route filters, you can do that. In this example we want to set up a filter for both before and after the route. Our goal is to create this class so that when you visit a route, Laravel will first check to see if the resulting HTML for that route has been served recently. If it has, return that HTML from the cache. We also want to make sure that when a user visits this route, if there is no cache present, Laravel will complete the grunt work of hitting the database, returning that data, rendering a view, and serving this response to the browser. We also want to make sure that when this entire process happens, this response data is first placed into cache before being presented to the user. That way, this data will be available in the cache for future requests. Great! We can handle the first part of this, checking the cache, in a before filter. We can handle writing to the cache with an after filter. Let’s pretend we already created all the backend code to handle this, what would our routes file look like?

  • 1: Determine How You Would Like to Call Your Filters

  • We’ll work backwards in this example. Let’s look at how we would set up our routes file so we can think about how we’d like to call these filters to handle getting and setting cache results for us.

    routes.php

    Notice that we chained both a before filter and an after filter to the home route by adding ->before('cache.grab')->after('cache.set'). We left the event listener in place to simply show us when we are getting data from the cache versus when we are getting data which is generated on the fly for us. Recall that when data comes from the cache, there will be no SQL dumped to the screen, whereas if there is a database hit, we will see the SQL displayed. Also, notice the convention of cache.grab and cache.set. We use the dot notation to remind us that grab and set will be methods defined in a dedicated class and resolved out of the IoC Container.

  • 2: Register Filter Names with IoC Container

  • Now that we know we’d like to have a before filter of cache.grab and an after filter of cache.set, we can configure our registration with the IoC. Open up app/filters.php and add this code at the end of the file to do just that. Note, the comments are also by us, so you can add those as well.

    These two lines simply map our two new filter names to method calls within the laratutFilters namespace in a CacheFilter class.

  • 3: Create Your Cache Class

  • The last step so get this to work is to actually create the class that will do the work for us. In our case, we create CacheFilter.php in the laratutFilters namespace. Note: We had already had this namespace set up from a prior lesson, and composer dump had already been run for this namespace. This means our files will autoload no problem, but if you are creating this lesson from scratch, you may need to add the namespace to your composer.json, and run composer dump.

    CacheFilter.php

So how does this class work? Let’s examine the whole flow of this code and we’ll better understand. When a user visits the home route, the cache.grab filter will be called before the request is loaded. This will trigger the grab method in the CacheFilter class. This method does the following:

  1. Creates a key based on the url of the route
  2. Uses this key to check the cache
  3. If this key already exists in cache, we can simply return that cached data

At this point, if the page is coming from cache, it will simply display to the browser. On the other hand, if the cache.grab does nothing since there was no key in the cache, Laravel will do what it normally does when you visit a route. It will query the database, render a view, filter view data, and so on. The user will get their expected result in the browser. Once this process is done, the after filter of cache.set will then trigger. This set method does the following for us:

  1. Creates a key based on the url of the route
  2. Uses this key to check the cache
  3. If this key does not exist, write the response to the cache using this key

If we test it out in the browser, it does appear to be working!


Initial Page Load
laravel cache example


Page Load 30 Seconds Later
laravel database cache


In addition to this, if we look in the app/storage/cache folder, we can find a file that does contain the full HTML contents. This data was placed in cache by our set method.

The Cache Conclusion

This was a fantastic crash course in getting up to speed with caching in a Laravel Application. By making use of Cache::put(), Cache::get(), Cache::has(), Cache::forever(), and the various other caching methods available, we can get and set cache in any number of ways. We also saw how we can register route filters and create a dedicated caching class to take care of this for us.