@@ -110,8 +110,8 @@ The route name (``blog_list``) is not important for now, but it will be essentia
110
110
:ref: `generating URLs <routing-generating-urls >`. You only have to keep in mind
111
111
that each route name must be unique in the application.
112
112
113
- Route HTTP Methods
114
- ~~~~~~~~~~~~~~~~~~
113
+ Matching HTTP Methods
114
+ ~~~~~~~~~~~~~~~~~~~~~
115
115
116
116
By default, routes match any HTTP verb (``GET ``, ``POST ``, ``PUT ``, etc.)
117
117
Use the ``methods `` option to restrict the verbs each route should respond to:
@@ -200,6 +200,102 @@ Use the ``methods`` option to restrict the verbs each route should respond to:
200
200
If you create your forms with :doc: `Symfony Forms </forms >` this is done
201
201
automatically for you.
202
202
203
+ Matching Expressions
204
+ ~~~~~~~~~~~~~~~~~~~~
205
+
206
+ Use the ``condition `` option if you need some route to match based on some
207
+ arbitrary matching logic:
208
+
209
+ .. configuration-block ::
210
+
211
+ .. code-block :: php-annotations
212
+
213
+ // src/Controller/DefaultController.php
214
+ namespace App\Controller;
215
+
216
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
217
+ use Symfony\Component\Routing\Annotation\Route;
218
+
219
+ class DefaultController extends AbstractController
220
+ {
221
+ /**
222
+ * @Route(
223
+ * "/contact",
224
+ * name="contact",
225
+ * condition="context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"
226
+ * )
227
+ *
228
+ * expressions can also include config parameters:
229
+ * condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'"
230
+ */
231
+ public function contact()
232
+ {
233
+ // ...
234
+ }
235
+ }
236
+
237
+ .. code-block :: yaml
238
+
239
+ # config/routes.yaml
240
+ contact :
241
+ path : /contact
242
+ controller : ' App\Controller\DefaultController::contact'
243
+ condition : " context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"
244
+ # expressions can also include config parameters:
245
+ # condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'"
246
+
247
+ .. code-block :: xml
248
+
249
+ <!-- config/routes.xml -->
250
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
251
+ <routes xmlns =" http://symfony.com/schema/routing"
252
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
253
+ xsi : schemaLocation =" http://symfony.com/schema/routing
254
+ https://symfony.com/schema/routing/routing-1.0.xsd" >
255
+
256
+ <route id =" contact" path =" /contact" controller =" App\Controller\DefaultController::contact" >
257
+ <condition >context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'</condition >
258
+ <!-- expressions can also include config parameters: -->
259
+ <!-- <condition>request.headers.get('User-Agent') matches '%app.allowed_browsers%'</condition> -->
260
+ </route >
261
+ </routes >
262
+
263
+ .. code-block :: php
264
+
265
+ // config/routes.php
266
+ use App\Controller\DefaultController;
267
+ use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
268
+
269
+ return function (RoutingConfigurator $routes) {
270
+ $routes->add('contact', '')
271
+ ->controller([DefaultController::class, 'contact'])
272
+ ->condition('context.getMethod() in ["GET", "HEAD"] and request.headers.get("User-Agent") matches "/firefox/i"')
273
+ // expressions can also include config parameters:
274
+ // 'request.headers.get("User-Agent") matches "%app.allowed_browsers%"'
275
+ ;
276
+ };
277
+
278
+ The value of the ``condition `` option is any valid
279
+ :doc: `ExpressionLanguage expression </components/expression_language/syntax >`
280
+ and can use and of these variables created by Symfony:
281
+
282
+ ``context ``
283
+ An instance of :class: `Symfony\\ Component\\ Routing\\ RequestContext `,
284
+ which holds the most fundamental information about the route being matched.
285
+
286
+ ``request ``
287
+ The :ref: `Symfony Request <component-http-foundation-request >` object that
288
+ represents the current request.
289
+
290
+ Behind the scenes, expressions are compiled down to raw PHP. Because of this,
291
+ using the ``condition `` key causes no extra overhead beyond the time it takes
292
+ for the underlying PHP to execute.
293
+
294
+ .. caution ::
295
+
296
+ Conditions are *not * taken into account when generating URLs (which is
297
+ explained later in this article).
298
+
203
299
Debugging Routes
204
300
~~~~~~~~~~~~~~~~
205
301
@@ -679,105 +775,6 @@ parameter:
679
775
To give a ``null `` default value to any parameter, add nothing after the
680
776
``? `` character (e.g. ``/blog/{page?} ``).
681
777
682
- .. _routing-expression_parameters :
683
-
684
- Expression Parameters
685
- ~~~~~~~~~~~~~~~~~~~~~
686
-
687
- Restricting routes via HTTP methods, host names and parameter validation is
688
- enough for most applications. However, if you need more flexibility to define
689
- arbitrary matching logic, you can use the ``condition `` option:
690
-
691
- .. configuration-block ::
692
-
693
- .. code-block :: php-annotations
694
-
695
- // src/Controller/DefaultController.php
696
- namespace App\Controller;
697
-
698
- use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
699
- use Symfony\Component\Routing\Annotation\Route;
700
-
701
- class DefaultController extends AbstractController
702
- {
703
- /**
704
- * @Route(
705
- * "/contact",
706
- * name="contact",
707
- * condition="context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"
708
- * )
709
- *
710
- * expressions can also include config parameters:
711
- * condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'"
712
- */
713
- public function contact()
714
- {
715
- // ...
716
- }
717
- }
718
-
719
- .. code-block :: yaml
720
-
721
- # config/routes.yaml
722
- contact :
723
- path : /contact
724
- controller : ' App\Controller\DefaultController::contact'
725
- condition : " context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"
726
- # expressions can also include config parameters:
727
- # condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'"
728
-
729
- .. code-block :: xml
730
-
731
- <!-- config/routes.xml -->
732
- <?xml version =" 1.0" encoding =" UTF-8" ?>
733
- <routes xmlns =" http://symfony.com/schema/routing"
734
- xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
735
- xsi : schemaLocation =" http://symfony.com/schema/routing
736
- https://symfony.com/schema/routing/routing-1.0.xsd" >
737
-
738
- <route id =" contact" path =" /contact" controller =" App\Controller\DefaultController::contact" >
739
- <condition >context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'</condition >
740
- <!-- expressions can also include config parameters: -->
741
- <!-- <condition>request.headers.get('User-Agent') matches '%app.allowed_browsers%'</condition> -->
742
- </route >
743
- </routes >
744
-
745
- .. code-block :: php
746
-
747
- // config/routes.php
748
- use App\Controller\DefaultController;
749
- use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
750
-
751
- return function (RoutingConfigurator $routes) {
752
- $routes->add('contact', '')
753
- ->controller([DefaultController::class, 'contact'])
754
- ->condition('context.getMethod() in ["GET", "HEAD"] and request.headers.get("User-Agent") matches "/firefox/i"')
755
- // expressions can also include config parameters:
756
- // 'request.headers.get("User-Agent") matches "%app.allowed_browsers%"'
757
- ;
758
- };
759
-
760
- The value of the ``condition `` option is any valid
761
- :doc: `ExpressionLanguage expression </components/expression_language/syntax >`
762
- where you can use any of these variables created by Symfony:
763
-
764
- ``context ``
765
- An instance of :class: `Symfony\\ Component\\ Routing\\ RequestContext `,
766
- which holds the most fundamental information about the route being matched.
767
-
768
- ``request ``
769
- The :ref: `Symfony Request <component-http-foundation-request >` object that
770
- represents the current request.
771
-
772
- Behind the scenes, expressions are compiled down to raw PHP. Because of this,
773
- using the ``condition `` key causes no extra overhead beyond the time it takes
774
- for the underlying PHP to execute.
775
-
776
- .. caution ::
777
-
778
- Conditions are *not * taken into account when generating URLs (which is
779
- explained later in this article).
780
-
781
778
Parameter Conversion
782
779
~~~~~~~~~~~~~~~~~~~~
783
780
0 commit comments