Implement caching with Symfony Cache component; configure pools, use cache tags for invalidation, and optimize performance
/plugin marketplace add MakFly/superpowers-symfony/plugin install makfly-superpowers-symfony@MakFly/superpowers-symfonyThis skill inherits all available tools. When active, it can use any tool Claude has access to.
composer require symfony/cache
<?php
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class ProductService
{
public function __construct(
private CacheInterface $cache,
) {}
public function getProduct(int $id): Product
{
return $this->cache->get("product_{$id}", function (ItemInterface $item) use ($id) {
$item->expiresAfter(3600); // 1 hour
return $this->repository->find($id);
});
}
}
$this->cache->delete("product_{$id}");
# config/packages/cache.yaml
framework:
cache:
# Default cache adapter
app: cache.adapter.redis
system: cache.adapter.system
# Define pools
pools:
cache.products:
adapter: cache.adapter.redis
default_lifetime: 3600
cache.api_responses:
adapter: cache.adapter.filesystem
default_lifetime: 300
cache.sessions:
adapter: cache.adapter.redis
default_lifetime: 86400
# .env
REDIS_URL=redis://localhost:6379
# config/packages/cache.yaml
framework:
cache:
app: cache.adapter.redis
default_redis_provider: '%env(REDIS_URL)%'
framework:
cache:
app: cache.adapter.filesystem
framework:
cache:
app: cache.adapter.apcu
framework:
cache:
pools:
cache.products:
adapters:
- cache.adapter.apcu # Fast, local
- cache.adapter.redis # Shared, persistent
<?php
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Contracts\Cache\CacheInterface;
class ProductService
{
public function __construct(
#[Autowire(service: 'cache.products')]
private CacheInterface $cache,
) {}
}
<?php
use Psr\Cache\CacheItemPoolInterface;
class LegacyService
{
public function __construct(
private CacheItemPoolInterface $cache,
) {}
public function getData(string $key): mixed
{
$item = $this->cache->getItem($key);
if (!$item->isHit()) {
$item->set($this->fetchData());
$item->expiresAfter(3600);
$this->cache->save($item);
}
return $item->get();
}
}
Tags allow invalidating groups of cache items:
<?php
use Symfony\Contracts\Cache\TagAwareCacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class ProductService
{
public function __construct(
private TagAwareCacheInterface $cache,
) {}
public function getProduct(int $id): Product
{
return $this->cache->get("product_{$id}", function (ItemInterface $item) use ($id) {
$item->expiresAfter(3600);
$item->tag(['products', "product_{$id}", "category_{$categoryId}"]);
return $this->repository->find($id);
});
}
public function getProductsByCategory(int $categoryId): array
{
return $this->cache->get("category_{$categoryId}_products", function (ItemInterface $item) use ($categoryId) {
$item->tag(['products', "category_{$categoryId}"]);
return $this->repository->findByCategory($categoryId);
});
}
public function invalidateProduct(int $id): void
{
// Invalidate specific product
$this->cache->invalidateTags(["product_{$id}"]);
}
public function invalidateCategory(int $categoryId): void
{
// Invalidate all products in category
$this->cache->invalidateTags(["category_{$categoryId}"]);
}
public function invalidateAllProducts(): void
{
// Invalidate all product caches
$this->cache->invalidateTags(['products']);
}
}
framework:
cache:
pools:
cache.products:
adapter: cache.adapter.redis
tags: true # Enable tag support
<?php
use Symfony\Component\HttpFoundation\Response;
class ProductController
{
#[Route('/products/{id}')]
public function show(Product $product): Response
{
$response = $this->render('product/show.html.twig', [
'product' => $product,
]);
// Public cache (CDN, proxy)
$response->setPublic();
$response->setMaxAge(3600);
$response->setSharedMaxAge(3600);
// ETag for validation
$response->setEtag(md5($response->getContent()));
return $response;
}
}
$response->headers->set('Cache-Control', 'public, max-age=3600, s-maxage=3600');
// Or using methods
$response->setPublic();
$response->setPrivate();
$response->setMaxAge(3600); // Browser cache
$response->setSharedMaxAge(3600); // CDN/proxy cache
$response->setExpires(new \DateTime('+1 hour'));
<?php
use Symfony\Component\HttpKernel\Attribute\Cache;
class ProductController
{
#[Route('/products/{id}')]
#[Cache(public: true, maxage: 3600, smaxage: 3600)]
public function show(Product $product): Response
{
return $this->render('product/show.html.twig', [
'product' => $product,
]);
}
}
<?php
// src/Cache/ProductCacheWarmer.php
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
class ProductCacheWarmer implements CacheWarmerInterface
{
public function __construct(
private ProductRepository $products,
private CacheInterface $cache,
) {}
public function warmUp(string $cacheDir, ?string $buildDir = null): array
{
foreach ($this->products->findPopular(100) as $product) {
$this->cache->get("product_{$product->getId()}", fn() => $product);
}
return [];
}
public function isOptional(): bool
{
return true;
}
}
# Clear all caches
bin/console cache:clear
# Clear specific pool
bin/console cache:pool:clear cache.products
# Clear by tag
bin/console cache:pool:invalidate-tags cache.products products
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.