Image created with Canva

When to Use Cache in PHP Symfony?

Serghei Pogor
6 min readApr 12, 2024

--

You might wonder, what’s that and why I need it?

Imagine you have a website… When people visit your website, they ask for information like photos, texts, and more. Your site goes to a big database to get that info each time.

But what if many people ask for the same thing? It can make the website slow. 😢 Here’s where cache comes to save the day!

Cache is like a magic box 🪄 that keeps copies of stuff that people ask for a lot. Next time someone asks for the same thing, your site can say, “Aha! I got it right here!” and show it super fast. Cool, right?

So, when is the best time to use this magic box in PHP Symfony? Let’s dive into some real code to see how it works and when to use it.

We’ll use PHP 8.3 and Symfony 7 for our examples because we want to stay trendy and powerful, right? 😉

Caching User Profiles

Let’s say you have a website where users can log in and see their profiles. Profiles don’t change often, but they are requested a lot.

This is a perfect chance to use cache!

Here’s how you might do it:

use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

class UserProfileController
{
public function showProfile(int $userId): Response
{
$cache = new FilesystemAdapter();
// Generating a unique cache key for the user profile
$cacheKey = 'user_profile_' . $userId;
// Fetching profile from cache or database if not cached
$profile = $cache->get($cacheKey, function (ItemInterface $item) use ($userId) {
$item->expiresAfter(3600); // Cache expires in one hour
// Fetch the profile from the database as usual
return $this->database->fetchUserProfile($userId);
});
// Render the profile view
return $this->render('profile.html.twig', ['profile' => $profile]);
}
}

In this code, we create a cache using Symfony’s FilesystemAdapter. We make a unique key for each user's profile so we don't mix them up. If the profile isn't in the cache, we go to the database, get it, and save it in the cache for next time. 🕒

This is a fantastic way to speed things up because the database is like a big library, and finding a book (or profile) can take time. But if you keep your most-read books near the door, you can grab them fast — that’s what caching does!

Caching Product Catalogs in an E-commerce Application

Let's take a real app, for example, lets suppose you’re running an online store where thousands of customers browse your products. Products don’t change every minute but are viewed very frequently. Here, cache becomes your best friend.

Let’s roll up our sleeves and see how we can implement caching for a product catalog:

use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

class ProductController
{
public function listProducts(): Response
{
$cache = new FilesystemAdapter();
// Cache key for products list
$cacheKey = 'product_list';
// Try to fetch the product list from cache
$products = $cache->get($cacheKey, function (ItemInterface $item) {
$item->expiresAfter(7200); // Cache expires in two hours
// If not in cache, fetch from database
return $this->database->fetchAllProducts();
});
// Render the product list view
return $this->render('products.html.twig', ['products' => $products]);
}
}

In this scenario, we use the cache to avoid hitting the database for every single request. Imagine having to run to the basement to fetch something every time your friend asks for it — not fun, right?

With cache, it’s like having those things right in your pocket! 🚀

Caching API Responses

Imagine your application needs to fetch weather information, stock prices, or news articles frequently from external APIs. These kinds of data don’t change every second but are requested very often by users. That’s a prime scenario for caching!

Here’s how you might cache API responses to make your application zippy and efficient:

use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

class WeatherController
{
public function getWeather(string $city): Response
{
$cache = new FilesystemAdapter();
// Unique cache key based on city
$cacheKey = 'weather_' . $city;
// Fetch weather data from cache or API if not cached
$weather = $cache->get($cacheKey, function (ItemInterface $item) use ($city) {
$item->expiresAfter(1800); // Cache expires in 30 minutes
// Call to external API to fetch weather
return $this->weatherApi->fetchWeather($city);
});
// Render the weather information
return $this->render('weather.html.twig', ['weather' => $weather]);
}
}

Caching saves the day by reducing the number of calls to the external API, which not only speeds up the response but also helps to avoid hitting API rate limits (a real headache if you’ve ever faced one!). 🌦️🚫

Monitoring Your Cache

Monitoring is key to understanding how well your cache is performing and when it might be causing more harm than good.

Here’s a simple way to start monitoring the performance of your cache:

use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\CacheItem;

class CacheMonitoringController
{
private $cache;
public function __construct()
{
$this->cache = new FilesystemAdapter();
}
public function checkCachePerformance(): Response
{
$stats = $this->cache->getStats();
return $this->render('cache_stats.html.twig', ['stats' => $stats]);
}
}

This can tell you how often your cache is hit versus missed.

When Might Caching Be Overkill?

While caching is fantastic, it’s not always the superhero we might imagine. Sometimes, caching can be like packing a huge suitcase for a weekend trip. It’s more than you need and can actually slow you down!

For example, if you have data that is accessed very infrequently and does not impact performance significantly, caching it might just complicate your life. It’s like wearing a heavy coat on a sunny day. Sure, it’s there if it gets cold, but you’ll be sweating until then! 😓

When Not to Use Cache

1. Highly Dynamic Data

If your application deals with data that changes almost as soon as it’s written — like real-time stock prices or live sports scores — caching might not make sense. Caching such rapidly changing information can lead to users seeing outdated data, which could be misleading or frustrating.

2. Rarely Accessed Data

Caching is most effective when it’s used for data that’s accessed frequently. If certain information is rarely requested, caching it can be a waste of resources. It’s like keeping ice cream in your hand all day hoping you’ll want it eventually — it’s going to melt before you get to enjoy it!

3. Small Datasets

When the data involved is small and the database query performance is already optimized, the overhead of implementing caching might outweigh its benefits. It’s like using a huge backpack to carry just a few feathers — unnecessary and cumbersome!

4. Sensitive Data

For sensitive information that needs to be highly secure, like personal user data or payment details, caching might introduce security risks unless handled with extra care. It’s crucial to ensure that cached data does not become a weak link in your security chain.

5. Data with Complex Dependency Rules

Some data might depend on several other pieces of data, and managing the dependencies to ensure coherence when something changes can be challenging. In such cases, caching could introduce errors if not managed meticulously. It’s like trying to change one gear in a watch without affecting the others — it requires precision and caution.

Handling Cache Expiration and Invalidity

Now, let’s sprinkle some wisdom on when caches need a refresh or a nudge to ensure data freshness.

Caching is powerful, but managing cache expiration is crucial. If you set it to expire too soon, you might as well not cache at all. Set it too late, and you risk showing outdated data. It’s like balancing a seesaw, you need to find the right balance that works for your specific needs.

Maintaining a cache isn’t just set-it-and-forget-it. It’s about fine-tuning and adjusting as your application evolves. You might find that what worked at the beginning doesn’t hold up as your user base grows or as data usage patterns change.

Remember, using cache is like planting a tree. 🌳

The best time was 20 years ago. The second-best time is now, especially if it makes your site faster and keeps your users happy!

🔔 Click Subscribe to catch more coding fun.
👏🏻 Love it? Give a big clap.
💬 Got a cool idea or funny coding joke? Drop it in the comments.

Share these tips with your fellow developers to help each other succeed together.

Thanks for hanging out and reading. You rock! 🚀

Hold on a sec!!! Want more of my fun stuff in your inbox? Sign up here! 📩

--

--

Serghei Pogor
Serghei Pogor

Written by Serghei Pogor

Good code is its own best documentation

No responses yet