1
1
.. index ::
2
2
single: Routing
3
+ single: Components; Routing
3
4
4
5
The Routing Component
5
- ====================
6
+ =====================
6
7
7
- The Routing Component maps a HTTP request to a set of configuration
8
+ The Routing Component maps an HTTP request to a set of configuration
8
9
variables.
9
10
10
11
Installation
@@ -25,8 +26,9 @@ In order to set up a basic routing system you need three parts:
25
26
* A :class: `Symfony\\ Component\\ Routing\\ RequestContext `, which has information about the request
26
27
* A :class: `Symfony\\ Component\\ Routing\\ Matcher\\ UrlMatcher `, which performs the mapping of the request to a single route
27
28
28
- .. code-block :: php
29
-
29
+ Let's see a quick example. Notice that this assumes that you've already configured
30
+ your autoloader to load the Routing component::
31
+
30
32
use Symfony\Component\Routing\Matcher\UrlMatcher;
31
33
use Symfony\Component\Routing\RequestContext;
32
34
use Symfony\Component\Routing\RouteCollection;
@@ -35,140 +37,165 @@ In order to set up a basic routing system you need three parts:
35
37
$routes = new RouteCollection();
36
38
$routes->add('route_name', new Route('/foo', array('controller' => 'MyController')));
37
39
38
- $context = new RequestContext();
40
+ $context = new RequestContext($_SERVER['REQUEST_URI'] );
39
41
40
42
$matcher = new UrlMatcher($routes, $context);
41
43
42
44
$parameters = $matcher->match( '/foo' );
43
45
// array('controller' => 'MyController', '_route' => 'route_name')
44
46
47
+ .. note ::
48
+
49
+ Be careful when using ``$_SERVER['REQUEST_URI'] ``, as it may include
50
+ any query parameters on the URL, which will cause problems with route
51
+ matching. An easy way to solve this is to use the HTTPFoundation component
52
+ as explained :ref: `below<components-routing-http-foundation> `.
53
+
45
54
You can add as many routes as you like to a
46
- :class: `Symfony\\ Component\\ Routing\\ RouteCollection `. The first argument you have to
47
- provide to the :method: `Symfony\\ Component\\ Routing\\ RouteCollection::add ` method is
48
- the name of the Route. The constructor of the :class: `Symfony\\ Component\\ Routing\\ Route `
49
- class expects an url path and an array of custom variables. These are returned by the
50
- Matcher if the route matches the request.
55
+ :class: `Symfony\\ Component\\ Routing\\ RouteCollection `.
56
+
57
+ The :method: `RouteCollection::add()<Symfony\\ Component\\ Routing\\ RouteCollection::add> `
58
+ method takes two arguments. The first is the name of the route, The second
59
+ is a :class: `Symfony\\ Component\\ Routing\\ Route ` object, which expects a
60
+ URL path and some array of custom variables in its constructor. This array
61
+ of custom variables can be *anything * that's significant to your application,
62
+ and is returned when that route is matched.
51
63
52
64
If no matching route can be found a
53
65
:class: `Symfony\\ Component\\ Routing\\ Exception\\ ResourceNotFoundException ` will be thrown.
54
66
55
- Additionally to the custom variables the name of the route is added with the
56
- key "_route" .
67
+ In addition to your array of custom variables, a `` _route `` key is added,
68
+ which holds the name of the matched route .
57
69
58
70
Defining routes
59
71
~~~~~~~~~~~~~~~
60
72
61
- A route contains:
73
+ A full route definition can contain up to four parts:
74
+
75
+ 1) The URL pattern route. This is matched against the URL passed to the `RequestContext `,
76
+ and can contain named wildcard placeholders (e.g. ``{placeholders} ``)
77
+ to match dynamic parts in the URL.
78
+
79
+ 2) An array of default values. This contains an array of arbitrary values
80
+ that will be returned when the request matches the route.
62
81
63
- * The path the of route, which shall be recognized by the matcher. You can use ``{placeholders} `` to match dynamic parts in the url.
64
- * The default values. These contain the values that will be returned when the request matches the route.
65
- * The requirements. These define constraints for the values of the placeholders as regular expressions.
66
- * The options. These contain internal settings for the route
82
+ 3) An array of requirements. These define constraints for the values of the
83
+ placeholders as regular expressions.
84
+
85
+ 4) An array of options. These contain internal settings for the route
86
+
87
+ Take the following route, which combines several of these ideas::
67
88
68
- .. code-block :: php
69
-
70
89
$route = new Route(
71
90
'/archive/{month}', // path
72
91
array('controller' => 'showArchive'), // default values
73
92
array('month' => '[0-9]{4}-[0-9]{2}'), // requirements
74
93
array() // options
75
94
);
76
-
95
+
77
96
// ...
78
-
97
+
79
98
$parameters = $matcher->match('/archive/2012-01');
80
99
// array('controller' => 'showArchive', 'month' => 2012-01'', '_route' => '...')
81
-
100
+
82
101
$parameters = $matcher->match('/archive/foo');
83
102
// throws ResourceNotFoundException
84
103
104
+ In this case, the route is matched by ``/archive/2012/01 ``, because the ``{month} ``
105
+ wildcard matches the regular expression wildcard given. However, ``/archive/foo ``
106
+ does *not * match, because "foo" fails the month wildcard.
107
+
85
108
Besides the regular expression constraints there are two special requirements
86
109
you can define:
87
110
88
111
* ``_method `` enforces a certain HTTP request method (``HEAD ``, ``GET ``, ``POST ``, ...)
89
112
* ``_scheme `` enforces a certain HTTP scheme (``http ``, ``https ``)
90
113
91
- .. code-block :: php
92
-
93
- // Only accepts requests to /foo with the POST method and a secure connection.
114
+ For example, the following route would only accept requests to /foo with
115
+ the POST method and a secure connection::
116
+
94
117
$route = new Route('/foo', array('_method' => 'post', '_scheme' => 'https' ));
95
118
96
- Using prefixes
119
+ Using Prefixes
97
120
~~~~~~~~~~~~~~
98
121
99
122
You can add routes or other instances of
100
- :class: `Symfony\\ Component\\ Routing\\ RouteCollection ` to a collection. This way
101
- you can build a tree of routes. Additionally you can define a prefix, default
102
- requirements and default options to all routes of a subtree:
123
+ :class: `Symfony\\ Component\\ Routing\\ RouteCollection ` to * another * collection.
124
+ This way you can build a tree of routes. Additionally you can define a prefix,
125
+ default requirements and default options to all routes of a subtree: :
103
126
104
- .. code-block :: php
105
-
106
127
$rootCollection = new RouteCollection();
107
-
128
+
108
129
$subCollection = new RouteCollection();
109
130
$subCollection->add( /*...*/ );
110
131
$subCollection->add( /*...*/ );
111
-
132
+
112
133
$rootCollection->addCollection($subCollection, '/prefix', array('_scheme' => 'https'));
113
134
114
- Set the request parameters
135
+ Set the Request Parameters
115
136
~~~~~~~~~~~~~~~~~~~~~~~~~~
116
137
117
138
The :class: `Symfony\\ Component\\ Routing\\ RequestContext ` provides information
118
- about a request. You can define all parameters of a HTTP request with this class:
139
+ about the current request. You can define all parameters of an HTTP request
140
+ with this class via its constructor::
119
141
120
- .. code-block :: php
121
-
122
142
public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443)
123
143
124
- Normally you can pass the values from the ``$_SERVER `` variable variable to the
125
- :class: `Symfony\\ Component\\ Routing\\ RequestContext `. If you use the
126
- :doc: `HttpFoundation<http_foundation> ` component you can use it's
144
+ .._components-routing-http-foundation:
145
+
146
+ Normally you can pass the values from the ``$_SERVER `` variable to populate the
147
+ :class: `Symfony\\ Component\\ Routing\\ RequestContext `. But If you use the
148
+ :doc: `HttpFoundation<http_foundation> ` component, you can use its
127
149
:class: `Symfony\\ Component\\ HttpFoundation\\ Request ` class to feed the
128
- :class: `Symfony\\ Component\\ Routing\\ RequestContext ` in a shortcut:
129
-
130
- .. code-block :: php
131
-
150
+ :class: `Symfony\\ Component\\ Routing\\ RequestContext ` in a shortcut::
151
+
132
152
use Symfony\Component\HttpFoundation\Request;
133
-
153
+
134
154
$context = new RequestContext();
135
155
$context->fromRequest(Request::createFromGlobals());
136
156
137
157
Generate a URL
138
158
~~~~~~~~~~~~~~
139
159
140
- While the :class: `Symfony\\ Component\\ Routing\\ Matcher\\ UrlMatcher ` tries to find
141
- a route that fits the given request you can also build an URL from a certain route:
160
+ While the :class: `Symfony\\ Component\\ Routing\\ Matcher\\ UrlMatcher ` tries
161
+ to find a route that fits the given request you can also build a URL from
162
+ a certain route::
142
163
143
- .. code-block :: php
144
-
145
164
use Symfony\Component\Routing\Generator\UrlGenerator;
146
165
147
166
$routes = new RouteCollection();
148
167
$routes->add('show_post', new Route('/show/{slug}'));
149
168
150
- $context = new RequestContext();
169
+ $context = new RequestContext($_SERVER['REQUEST_URI'] );
151
170
152
171
$generator = new UrlGenerator($routes, $context);
153
172
154
- $url = $generator->generate('show_post', 'My_Blog_Post');
155
- // /show/My_Blog_Post
173
+ $url = $generator->generate('show_post', array(
174
+ 'slug' => 'my-blog-post'
175
+ ));
176
+ // /show/my-blog-post
156
177
157
178
.. note ::
158
-
159
- If you have defined the ``_scheme `` requirement an absolute URL is generated
179
+
180
+ If you have defined the ``_scheme `` requirement, an absolute URL is generated
160
181
if the scheme of the current :class: `Symfony\\ Component\\ Routing\\ RequestContext `
161
- isn't the same .
182
+ does not match the requirement .
162
183
163
- Load routes from a file
184
+ Load Routes from a File
164
185
~~~~~~~~~~~~~~~~~~~~~~~
165
186
166
- There is a number of loader classes. They give you the ability to load a collection
167
- of route definitions from external files.
168
- The loaders expect a :class: `Symfony\\ Component\\ Config\\ FileLocator ` as the
169
- constructor argument. You can use the :class: `Symfony\\ Component\\ Config\\ FileLocator `
187
+ You've already seen how you can easily add routes to a collection right inside
188
+ PHP. But you can also load routes from a number of different files.
189
+
190
+ The Routing component comes with a number of loader classes, each giving
191
+ you the ability to load a collection of route definitions from an external
192
+ file of some format.
193
+ Each loader expects a :class: `Symfony\\ Component\\ Config\\ FileLocator ` instance
194
+ as the constructor argument. You can use the :class: `Symfony\\ Component\\ Config\\ FileLocator `
170
195
to define an array of paths in which the loader will look for the requested files.
171
- If the file could be found the loader returns a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `.
196
+ If the file is found, the loader returns a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `.
197
+
198
+ If you're using the ``YamlFileLoader ``, then route definitions look like this:
172
199
173
200
.. code-block :: yaml
174
201
@@ -181,11 +208,13 @@ If the file could be found the loader returns a :class:`Symfony\\Component\\Rout
181
208
pattern : /foo/bar
182
209
defaults : { controller: 'MyController::foobarAction' }
183
210
184
- .. code-block :: php
185
-
211
+ To load this file, you can use the following code. This assumes that your
212
+ ``routes.yml `` file is in the same directory as the below code::
213
+
186
214
use Symfony\Component\Config\FileLocator;
187
215
use Symfony\Component\Routing\Loader\YamlFileLoader;
188
216
217
+ // look inside *this* directory
189
218
$locator = new FileLocator(array(__DIR__));
190
219
$loader = new YamlFileLoader($locator);
191
220
$collection = $loader->load('routes.yml');
@@ -197,63 +226,69 @@ other loaders that work the same way:
197
226
* :class: `Symfony\\ Component\\ Routing\\ Loader\\ PhpFileLoader `
198
227
199
228
If you use the :class: `Symfony\\ Component\\ Routing\\ Loader\\ PhpFileLoader ` you
200
- have to provide the name of a php file which returns a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `:
229
+ have to provide the name of a php file which returns a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `::
201
230
202
- .. code-block :: php
203
-
204
231
// RouteProvider.php
205
232
use Symfony\Component\Routing\RouteCollection;
206
233
use Symfony\Component\Routing\Route;
207
234
208
235
$collection = new RouteCollection();
209
236
$collection->add('route_name', new Route('/foo', array('controller' => 'ExampleController')));
210
237
// ...
211
-
238
+
212
239
return $collection;
213
240
241
+ Routes as Closures
242
+ ..................
243
+
214
244
There is also the :class: `Symfony\\ Component\\ Routing\\ Loader\\ ClosureLoader `, which
215
- calls a closure and uses the result as a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `:
245
+ calls a closure and uses the result as a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `::
216
246
217
- .. code-block :: php
218
-
219
247
use Symfony\Component\Routing\Loader\ClosureLoader;
220
-
248
+
221
249
$closure = function() {
222
250
return new RouteCollection();
223
251
};
224
252
225
253
$loader = new ClosureLoader();
226
254
$collection = $loader->load($closure);
227
255
256
+ Routes as Annotations
257
+ .....................
258
+
228
259
Last but not least there are
229
260
:class: `Symfony\\ Component\\ Routing\\ Loader\\ AnnotationDirectoryLoader ` and
230
261
:class: `Symfony\\ Component\\ Routing\\ Loader\\ AnnotationFileLoader ` to load
231
- route definitions from class annotations.
262
+ route definitions from class annotations. The specific details are left
263
+ out here.
232
264
233
265
The all-in-one Router
234
266
~~~~~~~~~~~~~~~~~~~~~
235
267
236
- The :class: `Symfony\\ Component\\ Routing\\ Router ` class is a all-in-one package of
237
- the routing algorithm . The constructor expects a loader instance, a path to the
238
- main route definition and some other settings:
268
+ The :class: `Symfony\\ Component\\ Routing\\ Router ` class is a all-in-one package
269
+ to quickly use the Routing component . The constructor expects a loader instance,
270
+ a path to the main route definition and some other settings: :
239
271
240
- .. code-block :: php
241
-
242
272
public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, array $defaults = array());
243
273
244
274
With the ``cache_dir `` option you can enable route caching (if you provide a
245
275
path) or disable caching (if it's set to ``null ``). The caching is done
246
276
automatically in the background if you want to use it. A basic example of the
247
- :class: `Symfony\\ Component\\ Routing\\ Router ` class would look like:
277
+ :class: `Symfony\\ Component\\ Routing\\ Router ` class would look like::
248
278
249
- .. code-block :: php
250
-
251
279
$locator = new FileLocator(array(__DIR__));
252
- $router = new Router(new YamlFileLoader($locator), "routes.yml");
280
+ $requestContext = new RequestContext($_SERVER['REQUEST_URI']);
281
+
282
+ $router = new Router(
283
+ new YamlFileLoader($locator),
284
+ "routes.yml",
285
+ array('cache_dir' => __DIR__.'/cache'),
286
+ $requestContext,
287
+ );
253
288
$router->match('/foo/bar');
254
289
255
290
.. note ::
256
-
257
- If you use caching the Routing component will compile new classes which
291
+
292
+ If you use caching, the Routing component will compile new classes which
258
293
are saved in the ``cache_dir ``. This means your script must have write
259
294
permissions for that location.
0 commit comments