@@ -108,6 +108,91 @@ servers should not send ``Expires`` dates more than one year in the future."
108108 the ``Expires `` header value is ignored when the ``s-maxage `` or ``max-age ``
109109 directive of the ``Cache-Control `` header is defined.
110110
111+ Applying Cache Conditionally
112+ ----------------------------
113+
114+ .. versionadded ::
115+
116+ The ability to apply the ``#[Cache] `` attribute conditionally was introduced
117+ in Symfony 8.1.
118+
119+ You can use the ``if `` option to conditionally apply the ``#[Cache] `` attribute.
120+ This option accepts either a closure or an :doc: `ExpressionLanguage </components/expression_language >`
121+ expression that must return a boolean value:
122+
123+ .. configuration-block ::
124+
125+ .. code-block :: php-attributes
126+
127+ use Symfony\Component\HttpFoundation\Request;
128+ use Symfony\Component\HttpKernel\Attribute\Cache;
129+ // ...
130+
131+ // Using a closure
132+ #[Cache(
133+ public: true,
134+ maxage: 3600,
135+ if: fn (Request $request) => $request->query->has('cache')
136+ )]
137+ public function index(Request $request): Response
138+ {
139+ // ...
140+ }
141+
142+ // Using an expression
143+ #[Cache(
144+ public: true,
145+ maxage: 3600,
146+ if: "request.query.has('cache')"
147+ )]
148+ public function show(Request $request): Response
149+ {
150+ // ...
151+ }
152+
153+ The closure or expression has access to the ``Request `` object and controller
154+ arguments. When the condition evaluates to ``true ``, the cache headers are
155+ applied; when it evaluates to ``false ``, they are not.
156+
157+ This is particularly useful when:
158+
159+ * You need to enable caching programmatically based on runtime conditions
160+ * Your controller does not return a ``Response `` object directly (e.g. when using
161+ `FOSRestBundle `_ or other libraries that handle view rendering)
162+ * You want to cache based on user authentication, feature flags, or request parameters
163+
164+ Multiple Cache Attributes
165+ ~~~~~~~~~~~~~~~~~~~~~~~~~
166+
167+ The ``#[Cache] `` attribute is repeatable, allowing you to define multiple
168+ attributes with different conditions on the same controller:
169+
170+ .. code-block :: php-attributes
171+
172+ use Symfony\Component\HttpFoundation\Request;
173+ use Symfony\Component\HttpKernel\Attribute\Cache;
174+ // ...
175+
176+ #[Cache(
177+ public: true,
178+ maxage: 3600,
179+ if: fn (Request $request) => !$request->query->has('preview')
180+ )]
181+ #[Cache(
182+ public: false,
183+ maxage: 0,
184+ if: fn (Request $request) => $request->query->has('preview')
185+ )]
186+ public function article(Request $request): Response
187+ {
188+ // This will cache for 1 hour when preview=1 is NOT in the query string,
189+ // and disable caching when preview=1 IS present
190+ }
191+
192+ Only the first ``#[Cache] `` attribute whose condition evaluates to ``true ``
193+ will be applied. If no condition matches, no cache headers will be set by
194+ the attribute.
195+
111196.. _`expiration model` : https://tools.ietf.org/html/rfc2616#section-13.2
112197.. _`Calculating Freshness Lifetime` : https://tools.ietf.org/html/rfc7234#section-4.2.1
113198.. _`Serving Stale Responses` : https://tools.ietf.org/html/rfc7234#section-4.2.4
0 commit comments