Skip to content

Commit a53350c

Browse files
committed
[component][routing] Proofreading and tweaking the bootstrap for the routing component docs by @blogsh
1 parent 97ff5a9 commit a53350c

File tree

2 files changed

+121
-83
lines changed

2 files changed

+121
-83
lines changed

book/security.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
.. index::
2+
single: Security
3+
14
Security
25
========
36

components/routing.rst

Lines changed: 118 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
.. index::
22
single: Routing
3+
single: Components; Routing
34

45
The Routing Component
5-
====================
6+
=====================
67

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
89
variables.
910

1011
Installation
@@ -25,8 +26,9 @@ In order to set up a basic routing system you need three parts:
2526
* A :class:`Symfony\\Component\\Routing\\RequestContext`, which has information about the request
2627
* A :class:`Symfony\\Component\\Routing\\Matcher\\UrlMatcher`, which performs the mapping of the request to a single route
2728

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+
3032
use Symfony\Component\Routing\Matcher\UrlMatcher;
3133
use Symfony\Component\Routing\RequestContext;
3234
use Symfony\Component\Routing\RouteCollection;
@@ -35,140 +37,165 @@ In order to set up a basic routing system you need three parts:
3537
$routes = new RouteCollection();
3638
$routes->add('route_name', new Route('/foo', array('controller' => 'MyController')));
3739

38-
$context = new RequestContext();
40+
$context = new RequestContext($_SERVER['REQUEST_URI']);
3941

4042
$matcher = new UrlMatcher($routes, $context);
4143

4244
$parameters = $matcher->match( '/foo' );
4345
// array('controller' => 'MyController', '_route' => 'route_name')
4446

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+
4554
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.
5163

5264
If no matching route can be found a
5365
:class:`Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException` will be thrown.
5466

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.
5769

5870
Defining routes
5971
~~~~~~~~~~~~~~~
6072

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.
6281

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::
6788

68-
.. code-block:: php
69-
7089
$route = new Route(
7190
'/archive/{month}', // path
7291
array('controller' => 'showArchive'), // default values
7392
array('month' => '[0-9]{4}-[0-9]{2}'), // requirements
7493
array() // options
7594
);
76-
95+
7796
// ...
78-
97+
7998
$parameters = $matcher->match('/archive/2012-01');
8099
// array('controller' => 'showArchive', 'month' => 2012-01'', '_route' => '...')
81-
100+
82101
$parameters = $matcher->match('/archive/foo');
83102
// throws ResourceNotFoundException
84103

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+
85108
Besides the regular expression constraints there are two special requirements
86109
you can define:
87110

88111
* ``_method`` enforces a certain HTTP request method (``HEAD``, ``GET``, ``POST``, ...)
89112
* ``_scheme`` enforces a certain HTTP scheme (``http``, ``https``)
90113

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+
94117
$route = new Route('/foo', array('_method' => 'post', '_scheme' => 'https' ));
95118

96-
Using prefixes
119+
Using Prefixes
97120
~~~~~~~~~~~~~~
98121

99122
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::
103126

104-
.. code-block:: php
105-
106127
$rootCollection = new RouteCollection();
107-
128+
108129
$subCollection = new RouteCollection();
109130
$subCollection->add( /*...*/ );
110131
$subCollection->add( /*...*/ );
111-
132+
112133
$rootCollection->addCollection($subCollection, '/prefix', array('_scheme' => 'https'));
113134

114-
Set the request parameters
135+
Set the Request Parameters
115136
~~~~~~~~~~~~~~~~~~~~~~~~~~
116137

117138
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::
119141

120-
.. code-block:: php
121-
122142
public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443)
123143

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
127149
: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+
132152
use Symfony\Component\HttpFoundation\Request;
133-
153+
134154
$context = new RequestContext();
135155
$context->fromRequest(Request::createFromGlobals());
136156

137157
Generate a URL
138158
~~~~~~~~~~~~~~
139159

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::
142163

143-
.. code-block:: php
144-
145164
use Symfony\Component\Routing\Generator\UrlGenerator;
146165

147166
$routes = new RouteCollection();
148167
$routes->add('show_post', new Route('/show/{slug}'));
149168

150-
$context = new RequestContext();
169+
$context = new RequestContext($_SERVER['REQUEST_URI']);
151170

152171
$generator = new UrlGenerator($routes, $context);
153172

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
156177

157178
.. 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
160181
if the scheme of the current :class:`Symfony\\Component\\Routing\\RequestContext`
161-
isn't the same.
182+
does not match the requirement.
162183

163-
Load routes from a file
184+
Load Routes from a File
164185
~~~~~~~~~~~~~~~~~~~~~~~
165186

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`
170195
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:
172199

173200
.. code-block:: yaml
174201
@@ -181,11 +208,13 @@ If the file could be found the loader returns a :class:`Symfony\\Component\\Rout
181208
pattern: /foo/bar
182209
defaults: { controller: 'MyController::foobarAction' }
183210
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+
186214
use Symfony\Component\Config\FileLocator;
187215
use Symfony\Component\Routing\Loader\YamlFileLoader;
188216

217+
// look inside *this* directory
189218
$locator = new FileLocator(array(__DIR__));
190219
$loader = new YamlFileLoader($locator);
191220
$collection = $loader->load('routes.yml');
@@ -197,63 +226,69 @@ other loaders that work the same way:
197226
* :class:`Symfony\\Component\\Routing\\Loader\\PhpFileLoader`
198227

199228
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`::
201230

202-
.. code-block:: php
203-
204231
// RouteProvider.php
205232
use Symfony\Component\Routing\RouteCollection;
206233
use Symfony\Component\Routing\Route;
207234

208235
$collection = new RouteCollection();
209236
$collection->add('route_name', new Route('/foo', array('controller' => 'ExampleController')));
210237
// ...
211-
238+
212239
return $collection;
213240

241+
Routes as Closures
242+
..................
243+
214244
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`::
216246

217-
.. code-block:: php
218-
219247
use Symfony\Component\Routing\Loader\ClosureLoader;
220-
248+
221249
$closure = function() {
222250
return new RouteCollection();
223251
};
224252

225253
$loader = new ClosureLoader();
226254
$collection = $loader->load($closure);
227255

256+
Routes as Annotations
257+
.....................
258+
228259
Last but not least there are
229260
:class:`Symfony\\Component\\Routing\\Loader\\AnnotationDirectoryLoader` and
230261
: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.
232264

233265
The all-in-one Router
234266
~~~~~~~~~~~~~~~~~~~~~
235267

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::
239271

240-
.. code-block:: php
241-
242272
public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, array $defaults = array());
243273

244274
With the ``cache_dir`` option you can enable route caching (if you provide a
245275
path) or disable caching (if it's set to ``null``). The caching is done
246276
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::
248278

249-
.. code-block:: php
250-
251279
$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+
);
253288
$router->match('/foo/bar');
254289

255290
.. 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
258293
are saved in the ``cache_dir``. This means your script must have write
259294
permissions for that location.

0 commit comments

Comments
 (0)