Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cache Control Bundle Laravel Package

liip/cache-control-bundle

A Symfony bundle for setting HTTP Cache-Control and Expires headers on controller actions via annotations and configuration, making it easy to mark responses public, private, or uncached and work with reverse proxies.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is archived and deprecated (last release 2013-12-19) and was superseded by FOSHttpCacheBundle. The README is effectively a migration document. Before installing, decide which path applies:

  • New project: do not use this package. Use friendsofsymfony/http-cache-bundle with the friendsofsymfony/http-cache library.
  • Legacy Symfony 2.x application already pinned to it: keep it, but treat it as frozen and plan migration.

Minimal legacy setup:

  1. Require the package and register the bundle in AppKernel:
composer require liip/cache-control-bundle
// app/AppKernel.php
new Liip\CacheControlBundle\LiipCacheControlBundle(),
  1. Add configuration under liip_cache_control. The README examples are from the Symfony 2.0 era, so treat DependencyInjection/Configuration.php as the authoritative schema. The core idea is rules that map request paths to Cache-Control directives, plus a reverse-proxy/Varnish section:
# app/config/config.yml — verify key names against Configuration.php
liip_cache_control:
    rules:
        - path: ^/$
          controls:
              public: true
              max_age: 300
  1. Clear the container cache and verify the header on the wire:
curl -sI http://localhost/ | grep -i cache-control

First use case: make an anonymous, read-only page (homepage, product listing, article detail) cacheable at the shared-cache level, then confirm Cache-Control: public, max-age=... and s-maxage are present. The bundle's value is applying those headers centrally — by path or controller/action annotation — rather than sprinkling $response->setPublic() through every controller.

Where to look first:

  • README.md — deprecation notice and the migration mapping to FOSHttpCacheBundle.
  • DependencyInjection/Configuration.php — real config keys and defaults.
  • Annotation/ — controller-level cache annotations.
  • Resources/config/services.xml — service IDs for the cache manager and Varnish client.
  • The README migration table — it tells you exactly which FOSHttpCacheBundle option replaces each Liip option.

For a migration target, the equivalent FOSHttpCacheBundle configuration is:

fos_http_cache:
    cache_control:
        rules:
            - match:
                  path: ^/$
                  methods: [GET, HEAD]
              headers:
                  cache_control:
                      public: true
                      max_age: 300
    proxy_client:
        varnish:
            servers: [localhost:6081]

Implementation Patterns

1. Config rules first, annotations second. Use path-based rules for broad policy (static sections, listings, health checks) and annotations only for action-specific overrides. Centralizing policy avoids the classic problem of one controller forgetting setPublic() and poisoning a shared cache with a private response.

2. Controller annotations for per-action intent. In legacy code you typically see annotations on the action:

use Liip\CacheControlBundle\Annotation\Cache;

/**
 * @Cache(public=true, maxAge=60)
 */
public function showAction($id) { /* ... */ }

Verify the exact annotation class/property names in the bundle's Annotation/ directory — the naming differed from FOSHttpCacheBundle's @Cache, so do not copy modern examples directly.

3. Purge on write, not just expire. Configure the shortest sane TTL, then explicitly invalidate when content changes. The bundle exposes a Varnish client/cache-manager service; locate the service ID in services.xml and inject it into the service that writes content, or better, into a kernel.terminate / domain event listener so the purge happens after the database transaction commits:

public function onContentUpdated(ContentUpdatedEvent $event)
{
    $this->cacheManager->invalidate($event->getUrl());
}

A purge-before-commit is a common source of stale-then-repopulated cache entries.

4. Use s-maxage, not only max-age. With a shared proxy in front, max-age controls browsers and s-maxage controls Varnish. Symfony's Response::setSharedMaxAge() sets s-maxage and marks the response public — prefer it over manually assembling headers.

5. ESI for fragment-level caching. Cache the page shell aggressively and use ESI/Surrogate-Control for personalized fragments (cart count, user greeting). This is the safe way to cache pages for authenticated users without leaking one user's data to another.

6. Test the headers, not the bundle. Add functional tests asserting Cache-Control on key routes and integration tests that assert purge calls against a mocked HTTP client. Because the package is unmaintained, your test suite is the only regression net you have.

7. Migration pattern. When moving to FOSHttpCacheBundle, migrate in this order: (a) move config rules, (b) replace annotations, (c) swap the Varnish client for the FOSHttpCache library client, (d) enable tags/ban invalidation, (e) remove the Liip bundle. Both bundles cannot coexist cleanly — they overlap in services and annotations.

Gotchas and Tips

  • Abandoned since 2013. No security fixes, no PHP 7/8 or Symfony 3+ compatibility. Composer will usually surface it as abandoned; dependency resolution against modern packages will fail. This is the dominant risk, not a footnote.
  • Zero dependents and no recent releases mean edge cases are undocumented. Read the source, especially Configuration.php, before trusting any blog post.
  • Header precedence is subtle. Controller-set headers, bundle rules, and annotations can disagree. Decide one precedence order and verify with curl -I; don't assume annotations win over config.
  • Accidentally caching authenticated responses. Always send Cache-Control: private, no-cache (or omit public caching entirely) for logged-in pages, and set Vary: Cookie / Vary: Authorization where appropriate. A single misconfigured rule can serve one user's account page to another.
  • Varnish purge failures are silent. Wrong host/port, a VCL that ignores PURGE/BAN, or a purge sent before commit all look like "caching works but content is stale." Check varnishlog and assert purge responses in tests.
  • public does not mean "cache forever." Combine public with a short s-maxage and explicit purges; long TTLs plus missed invalidations produce the worst debugging sessions.
  • ESI requires surrogate support. Without a proxy that handles ESI (or Symfony's HttpCache with ESI enabled), the <esi:include> tags reach the browser and do nothing.
  • Debugging checklist: curl -sI, X-Cache/Age headers, Varnish varnishlog -g request, Symfony profiler's response panel, and a container dump (debug:container) to confirm which cache service is actually wired.
  • Extension points are limited but real: custom purge clients and kernel.response listeners are the practical hooks. Avoid subclassing bundle internals — they were not designed as a stable API and will not receive fixes.
  • Treat this assessment as a migration trigger. If the package appears in composer.json, schedule replacement with FOSHttpCacheBundle; the README's migration guide is the shortest path and the only supported direction.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle