@@ -21,5 +21,286 @@ Installation
21
21
Usage
22
22
-----
23
23
24
- The documentation about using this component has been moved to the
25
- main :doc: `Symfony routing </routing >` article.
24
+ The main :doc: `Symfony routing </routing >` article explains all the features of
25
+ this component when used inside a Symfony application. This article only
26
+ explains the things you need to do to use it in a non-Symfony PHP application.
27
+
28
+ Routing System Setup
29
+ --------------------
30
+
31
+ A routing system has three parts:
32
+
33
+ * A :class: `Symfony\\ Component\\ Routing\\ RouteCollection `, which contains the
34
+ route definitions (instances of the class :class: `Symfony\\ Component\\ Routing\\ Route `);
35
+ * A :class: `Symfony\\ Component\\ Routing\\ RequestContext `, which has information
36
+ about the request;
37
+ * A :class: `Symfony\\ Component\\ Routing\\ Matcher\\ UrlMatcher `, which performs
38
+ the mapping of the path to a single route.
39
+
40
+ Here is a quick example::
41
+
42
+ use App\Controller\BlogController;
43
+ use Symfony\Component\Routing\Matcher\UrlMatcher;
44
+ use Symfony\Component\Routing\RequestContext;
45
+ use Symfony\Component\Routing\Route;
46
+ use Symfony\Component\Routing\RouteCollection;
47
+
48
+ $route = new Route('/blog/{slug}', ['_controller' => BlogController::class])
49
+ $routes = new RouteCollection();
50
+ $routes->add('blog_show', $route);
51
+
52
+ $context = new RequestContext('/');
53
+
54
+ // Routing can match routes with incoming requests
55
+ $matcher = new UrlMatcher($routes, $context);
56
+ $parameters = $matcher->match('/blog/lorem-ipsum');
57
+ // $parameters = [
58
+ // '_controller' => 'App\Controller\BlogController',
59
+ // 'slug' => 'lorem-ipsum',
60
+ // '_route' => 'blog_show'
61
+ // ]
62
+
63
+ // Routing can also generate URLs for a given route
64
+ $generator = new UrlGenerator($routes, $context);
65
+ $url = $generator->generate('blog_show', [
66
+ 'slug' => 'my-blog-post',
67
+ ]);
68
+ // $url = '/blog/my-blog-post'
69
+
70
+ The :method: `RouteCollection::add() <Symfony\\ Component\\ Routing\\ RouteCollection::add> `
71
+ method takes two arguments. The first is the name of the route. The second
72
+ is a :class: `Symfony\\ Component\\ Routing\\ Route ` object, which expects a
73
+ URL path and some array of custom variables in its constructor. This array
74
+ of custom variables can be *anything * that's significant to your application,
75
+ and is returned when that route is matched.
76
+
77
+ The :method: `UrlMatcher::match() <Symfony\\ Component\\ Routing\\ Matcher\\ UrlMatcher::match> `
78
+ returns the variables you set on the route as well as the route parameters.
79
+ Your application can now use this information to continue processing the request.
80
+ In addition to the configured variables, a ``_route `` key is added, which holds
81
+ the name of the matched route.
82
+
83
+ If no matching route can be found, a
84
+ :class: `Symfony\\ Component\\ Routing\\ Exception\\ ResourceNotFoundException ` will
85
+ be thrown.
86
+
87
+ Defining Routes
88
+ ---------------
89
+
90
+ A full route definition can contain up to eight parts::
91
+
92
+ $route = new Route(
93
+ '/archive/{month}', // path
94
+ ['_controller' => 'showArchive'], // default values
95
+ ['month' => '[0-9]{4}-[0-9]{2}', 'subdomain' => 'www|m'], // requirements
96
+ [], // options
97
+ '{subdomain}.example.com', // host
98
+ [], // schemes
99
+ [], // methods
100
+ 'context.getHost() matches "/(secure|admin).example.com/"' // condition
101
+ );
102
+
103
+ // ...
104
+
105
+ $parameters = $matcher->match('/archive/2012-01');
106
+ // [
107
+ // '_controller' => 'showArchive',
108
+ // 'month' => '2012-01',
109
+ // 'subdomain' => 'www',
110
+ // '_route' => ...
111
+ // ]
112
+
113
+ $parameters = $matcher->match('/archive/foo');
114
+ // throws ResourceNotFoundException
115
+
116
+ Route Collections
117
+ -----------------
118
+
119
+ You can add routes or other instances of
120
+ :class: `Symfony\\ Component\\ Routing\\ RouteCollection ` to *another * collection.
121
+ This way you can build a tree of routes. Additionally you can define common
122
+ options for all routes of a subtree using methods provided by the
123
+ ``RouteCollection `` class::
124
+
125
+ $rootCollection = new RouteCollection();
126
+
127
+ $subCollection = new RouteCollection();
128
+ $subCollection->add(...);
129
+ $subCollection->add(...);
130
+ $subCollection->addPrefix('/prefix');
131
+ $subCollection->addDefaults([...]);
132
+ $subCollection->addRequirements([...]);
133
+ $subCollection->addOptions([...]);
134
+ $subCollection->setHost('{subdomain}.example.com');
135
+ $subCollection->setMethods(['POST']);
136
+ $subCollection->setSchemes(['https']);
137
+ $subCollection->setCondition('context.getHost() matches "/(secure|admin).example.com/"');
138
+
139
+ $rootCollection->addCollection($subCollection);
140
+
141
+ Setting the Request Parameters
142
+ ------------------------------
143
+
144
+ The :class: `Symfony\\ Component\\ Routing\\ RequestContext ` provides information
145
+ about the current request. You can define all parameters of an HTTP request
146
+ with this class via its constructor::
147
+
148
+ public function __construct(
149
+ $baseUrl = '',
150
+ $method = 'GET',
151
+ $host = 'localhost',
152
+ $scheme = 'http',
153
+ $httpPort = 80,
154
+ $httpsPort = 443,
155
+ $path = '/',
156
+ $queryString = ''
157
+ )
158
+
159
+ .. _components-routing-http-foundation :
160
+
161
+ Normally you can pass the values from the ``$_SERVER `` variable to populate the
162
+ :class: `Symfony\\ Component\\ Routing\\ RequestContext `. But if you use the
163
+ :doc: `HttpFoundation </components/http_foundation >` component, you can use its
164
+ :class: `Symfony\\ Component\\ HttpFoundation\\ Request ` class to feed the
165
+ :class: `Symfony\\ Component\\ Routing\\ RequestContext ` in a shortcut::
166
+
167
+ use Symfony\Component\HttpFoundation\Request;
168
+
169
+ $context = new RequestContext();
170
+ $context->fromRequest(Request::createFromGlobals());
171
+
172
+ Loading Routes
173
+ --------------
174
+
175
+ The Routing component comes with a number of loader classes, each giving you the
176
+ ability to load a collection of route definitions from external resources.
177
+
178
+ File Routing Loaders
179
+ ~~~~~~~~~~~~~~~~~~~~
180
+
181
+ Each loader expects a :class: `Symfony\\ Component\\ Config\\ FileLocator ` instance
182
+ as the constructor argument. You can use the :class: `Symfony\\ Component\\ Config\\ FileLocator `
183
+ to define an array of paths in which the loader will look for the requested files.
184
+ If the file is found, the loader returns a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `.
185
+
186
+ If you're using the ``YamlFileLoader ``, then route definitions look like this:
187
+
188
+ .. code-block :: yaml
189
+ # routes.yaml
190
+ route1 :
191
+ path : /foo
192
+ controller : MyController::fooAction
193
+ methods : GET|HEAD
194
+ route2 :
195
+ path : /foo/bar
196
+ controller : FooBarInvokableController
197
+ methods : PUT
198
+ To load this file, you can use the following code. This assumes that your
199
+ ``routes.yaml `` file is in the same directory as the below code::
200
+
201
+ use Symfony\Component\Config\FileLocator;
202
+ use Symfony\Component\Routing\Loader\YamlFileLoader;
203
+
204
+ // looks inside *this* directory
205
+ $fileLocator = new FileLocator([__DIR__]);
206
+ $loader = new YamlFileLoader($fileLocator);
207
+ $routes = $loader->load('routes.yaml');
208
+
209
+ Besides :class: `Symfony\\ Component\\ Routing\\ Loader\\ YamlFileLoader ` there are two
210
+ other loaders that work the same way:
211
+
212
+ * :class: `Symfony\\ Component\\ Routing\\ Loader\\ XmlFileLoader `
213
+ * :class: `Symfony\\ Component\\ Routing\\ Loader\\ PhpFileLoader `
214
+
215
+ If you use the :class: `Symfony\\ Component\\ Routing\\ Loader\\ PhpFileLoader ` you
216
+ have to provide the name of a PHP file which returns a callable handling a
217
+ :class: `Symfony\\ Component\\ Routing\\ Loader\\ Configurator\\ RoutingConfigurator `.
218
+ This class allows to chain imports, collections or simple route definition calls::
219
+
220
+ // RouteProvider.php
221
+ use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
222
+
223
+ return function (RoutingConfigurator $routes) {
224
+ $routes->add('route_name', '/foo')
225
+ ->controller('ExampleController')
226
+ // ...
227
+ ;
228
+ };
229
+
230
+ Closure Routing Loaders
231
+ ~~~~~~~~~~~~~~~~~~~~~~~
232
+
233
+ There is also the :class: `Symfony\\ Component\\ Routing\\ Loader\\ ClosureLoader `, which
234
+ calls a closure and uses the result as a :class: `Symfony\\ Component\\ Routing\\ RouteCollection `::
235
+
236
+ use Symfony\Component\Routing\Loader\ClosureLoader;
237
+
238
+ $closure = function () {
239
+ return new RouteCollection();
240
+ };
241
+
242
+ $loader = new ClosureLoader();
243
+ $routes = $loader->load($closure);
244
+
245
+ Annotation Routing Loaders
246
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
247
+
248
+ Last but not least there are
249
+ :class: `Symfony\\ Component\\ Routing\\ Loader\\ AnnotationDirectoryLoader ` and
250
+ :class: `Symfony\\ Component\\ Routing\\ Loader\\ AnnotationFileLoader ` to load
251
+ route definitions from class annotations. The specific details are left
252
+ out here.
253
+
254
+ .. include :: /_includes/_annotation_loader_tip.rst.inc
255
+
256
+ The all-in-one Router
257
+ ~~~~~~~~~~~~~~~~~~~~~
258
+
259
+ The :class: `Symfony\\ Component\\ Routing\\ Router ` class is an all-in-one package
260
+ to use the Routing component. The constructor expects a loader instance,
261
+ a path to the main route definition and some other settings::
262
+
263
+ public function __construct(
264
+ LoaderInterface $loader,
265
+ $resource,
266
+ array $options = [],
267
+ RequestContext $context = null,
268
+ LoggerInterface $logger = null
269
+ );
270
+
271
+ With the ``cache_dir `` option you can enable route caching (if you provide a
272
+ path) or disable caching (if it's set to ``null ``). The caching is done
273
+ automatically in the background if you want to use it. A basic example of the
274
+ :class: `Symfony\\ Component\\ Routing\\ Router ` class would look like::
275
+
276
+ $fileLocator = new FileLocator([__DIR__]);
277
+ $requestContext = new RequestContext('/');
278
+
279
+ $router = new Router(
280
+ new YamlFileLoader($fileLocator),
281
+ 'routes.yaml',
282
+ ['cache_dir' => __DIR__.'/cache'],
283
+ $requestContext
284
+ );
285
+ $parameters = $router->match('/foo/bar');
286
+ $url = $router->generate('some_route', ['parameter' => 'value']);
287
+
288
+ .. note ::
289
+
290
+ If you use caching, the Routing component will compile new classes which
291
+ are saved in the ``cache_dir ``. This means your script must have write
292
+ permissions for that location.
293
+
294
+ Learn more
295
+ ----------
296
+
297
+ .. toctree ::
298
+ :maxdepth: 1
299
+ :glob:
300
+
301
+ /routing
302
+ /routing/*
303
+ /controller
304
+ /controller/*
305
+
306
+ .. _Packagist : https://packagist.org/packages/symfony/routing
0 commit comments