diff --git a/controller.rst b/controller.rst
index b44b8273672..102ca934e3f 100644
--- a/controller.rst
+++ b/controller.rst
@@ -4,42 +4,12 @@
Controller
==========
-A controller is a PHP function you create that reads information from the Symfony's
+A controller is a PHP function you create that reads information from the
``Request`` object and creates and returns a ``Response`` object. The response could
be an HTML page, JSON, XML, a file download, a redirect, a 404 error or anything
else you can dream up. The controller executes whatever arbitrary logic
*your application* needs to render the content of a page.
-See how simple this is by looking at a Symfony controller in action.
-This renders a page that prints a lucky (random) number::
-
- // src/Controller/LuckyController.php
- namespace App\Controller;
-
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\Routing\Annotation\Route;
-
- class LuckyController
- {
- /**
- * @Route("/lucky/number")
- */
- public function numberAction()
- {
- $number = mt_rand(0, 100);
-
- return new Response(
- '
Lucky number: '.$number.''
- );
- }
- }
-
-But in the real world, your controller will probably do a lot of work in order to
-create the response. It might read information from the request, load a database
-resource, send an email or set information on the user's session.
-But in all cases, the controller will eventually return the ``Response`` object
-that will be delivered back to the client.
-
.. tip::
If you haven't already created your first working page, check out
@@ -64,9 +34,9 @@ class::
class LuckyController
{
/**
- * @Route("/lucky/number/{max}")
+ * @Route("/lucky/number/{max}", name="app_lucky_number")
*/
- public function numberAction($max)
+ public function number($max)
{
$number = mt_rand(0, $max);
@@ -76,7 +46,7 @@ class::
}
}
-The controller is the ``numberAction()`` method, which lives inside a
+The controller is the ``number()`` method, which lives inside a
controller class ``LuckyController``.
This controller is pretty straightforward:
@@ -89,12 +59,10 @@ This controller is pretty straightforward:
must return.
* *line 7*: The class can technically be called anything - but should end in the
- word ``Controller`` (this isn't *required*, but some shortcuts rely on this).
+ word ``Controller``
-* *line 12*: Each action method in a controller class is suffixed with ``Action``
- (again, this isn't *required*, but some shortcuts rely on this). This method
- is allowed to have a ``$max`` argument thanks to the ``{max}``
- :doc:`wildcard in the route `.
+* *line 12*: The action method is allowed to have a ``$max`` argument thanks to the
+ ``{max}`` :doc:`wildcard in the route `.
* *line 16*: The controller creates and returns a ``Response`` object.
@@ -105,7 +73,8 @@ Mapping a URL to a Controller
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to *view* the result of this controller, you need to map a URL to it via
-a route. This was done above with the ``@Route("/lucky/number/{max}")`` annotation.
+a route. This was done above with the ``@Route("/lucky/number/{max}")``
+:ref:`route annotation `.
To see your page, go to this URL in your browser:
@@ -121,20 +90,23 @@ For more information on routing, see :doc:`/routing`.
The Base Controller Classes & Services
--------------------------------------
-For convenience, Symfony comes with two optional base
+To make life nicer, Symfony comes with two optional base
:class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` and
-:class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController`
-classes. You can extend either to get access to a number of `helper methods`_.
+:class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController`.
+You can extend either to get access to some `helper methods`_.
-Add the ``use`` statement atop the ``Controller`` class and then modify
-``LuckyController`` to extend it::
+Add the ``use`` statement atop your controller class and then modify
+``LuckyController`` to extend it:
+
+.. code-block:: diff
// src/Controller/LuckyController.php
namespace App\Controller;
- use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+ + use Symfony\Bundle\FrameworkBundle\Controller\Controller;
- class LuckyController extends Controller
+ - class LuckyController
+ + class LuckyController extends Controller
{
// ...
}
@@ -146,11 +118,12 @@ and many others that you'll learn about next.
.. tip::
- You can extend either ``Controller`` or ``AbstractController``. The difference
- is that when you extend ``AbstractController``, you can't access services directly
- via ``$this->get()`` or ``$this->container->get()``. This forces you to write
- more robust code to access services. But if you *do* need direct access to the
- container, using ``Controller`` is fine.
+ What's the difference between ``Controller`` or ``AbstractController``? Not much:
+ both are identical, except that ``AbstractController`` is more restrictive: it
+ does not allow you to access services directly via ``$this->get()`` or
+ ``$this->container->get()``. This forces you to write more robust code to access
+ services. But if you *do* need direct access to the container, using ``Controller``
+ is fine.
.. index::
single: Controller; Redirecting
@@ -161,7 +134,7 @@ Generating URLs
The :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::generateUrl`
method is just a helper method that generates the URL for a given route::
- $url = $this->generateUrl('blog_show', array('slug' => 'slug-value'));
+ $url = $this->generateUrl('app_lucky_number', array('max' => 10));
Redirecting
~~~~~~~~~~~
@@ -169,43 +142,33 @@ Redirecting
If you want to redirect the user to another page, use the ``redirectToRoute()``
and ``redirect()`` methods::
+ use Symfony\Component\HttpFoundation\RedirectResponse;
+
+ // ...
public function indexAction()
{
// redirect to the "homepage" route
return $this->redirectToRoute('homepage');
+ // redirectToRoute is a shortcut for:
+ // return new RedirectResponse($this->generateUrl('homepage'));
+
// do a permanent - 301 redirect
return $this->redirectToRoute('homepage', array(), 301);
// redirect to a route with parameters
- return $this->redirectToRoute('blog_show', array('slug' => 'my-page'));
+ return $this->redirectToRoute('app_lucky_number', array('max' => 10));
// redirect externally
return $this->redirect('http://symfony.com/doc');
}
-For more information, see the :doc:`Routing article `.
-
.. caution::
The ``redirect()`` method does not check its destination in any way. If you
- redirect to some URL provided by the end-users, your application may be open
+ redirect to a URL provided by end-users, your application may be open
to the `unvalidated redirects security vulnerability`_.
-
-.. tip::
-
- The ``redirectToRoute()`` method is simply a shortcut that creates a
- ``Response`` object that specializes in redirecting the user. It's
- equivalent to::
-
- use Symfony\Component\HttpFoundation\RedirectResponse;
-
- public function indexAction()
- {
- return new RedirectResponse($this->generateUrl('homepage'));
- }
-
.. index::
single: Controller; Rendering templates
@@ -221,24 +184,17 @@ object for you::
// renders templates/lucky/number.html.twig
return $this->render('lucky/number.html.twig', array('name' => $name));
-Templates can also live in deeper sub-directories. Just try to avoid
-creating unnecessarily deep structures::
-
- // renders templates/lottery/lucky/number.html.twig
- return $this->render('lottery/lucky/number.html.twig', array(
- 'name' => $name,
- ));
-
-The Symfony templating system and Twig are explained more in the
+Templating and Twig are explained more in the
:doc:`Creating and Using Templates article `.
.. index::
single: Controller; Accessing services
.. _controller-accessing-services:
+.. _accessing-other-services:
-Fetching Services as Controller Arguments
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Fetching Services
+~~~~~~~~~~~~~~~~~
Symfony comes *packed* with a lot of useful objects, called :doc:`services `.
These are used for rendering templates, sending emails, querying the database and
@@ -334,26 +290,12 @@ in your controllers.
For more information about services, see the :doc:`/service_container` article.
-.. _controller-service-arguments-tag:
-
-.. note::
- If this isn't working, make sure your controller is registered as a service,
- is :ref:`autoconfigured ` and extends either
- :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` or
- :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController`. If
- you use the :ref:`services.yaml configuration from the Symfony Standard Edition `,
- then your controllers are already registered as services and autoconfigured.
-
- If you're not using the default configuration, you can tag your service manually
- with ``controller.service_arguments``.
-
-.. _accessing-other-services:
.. _controller-access-services-directly:
Accessing the Container Directly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If you extend the base ``Controller`` class, you can access any Symfony service
+If you extend the base ``Controller`` class, you can access :ref:`public services `
via the :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::get`
method. Here are several common services you might need::
@@ -382,40 +324,44 @@ and that it's :ref:`public `.
Managing Errors and 404 Pages
-----------------------------
-When things are not found, you should play well with the HTTP protocol and
-return a 404 response. To do this, you'll throw a special type of exception.
-If you're extending the base ``Controller`` or the base ``AbstractController``
-class, do the following::
+When things are not found, you should return a 404 response. To do this, throw a
+special type of exception::
+
+ use Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;
+ // ...
public function indexAction()
{
// retrieve the object from database
$product = ...;
if (!$product) {
throw $this->createNotFoundException('The product does not exist');
+
+ // the above is just a shortcut for:
+ // throw new NotFoundHttpException('The product does not exist');
}
return $this->render(...);
}
-The :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::createNotFoundException`
+The :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerTrait::createNotFoundException`
method is just a shortcut to create a special
:class:`Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException`
object, which ultimately triggers a 404 HTTP response inside Symfony.
-Of course, you're free to throw any ``Exception`` class in your controller -
-Symfony will automatically return a 500 HTTP response code.
+Of course, you can throw any ``Exception`` class in your controller: Symfony will
+automatically return a 500 HTTP response code.
.. code-block:: php
throw new \Exception('Something went wrong!');
In every case, an error page is shown to the end user and a full debug
-error page is shown to the developer (i.e. when you're using the ``index.php``
-front controller - see :ref:`page-creation-environments`).
+error page is shown to the developer (i.e. when you're in "Debug" mode - see
+:ref:`page-creation-environments`).
-You'll want to customize the error page your user sees. To do that, see
-the :doc:`/controller/error_pages` article.
+To customize the error page that's shown to the user, see the
+:doc:`/controller/error_pages` article.
.. _controller-request-argument:
@@ -448,54 +394,28 @@ Request object.
Managing the Session
--------------------
-Symfony provides a nice session object that you can use to store information
-about the user between requests. By default, Symfony stores the token in a
-cookie and writes the attributes to a file by using native PHP sessions.
-
-First, enable sessions in your configuration:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # config/packages/framework.yaml
- framework:
- # ...
-
- session:
- # With this config, PHP's native session handling is used
- handler_id: ~
+Symfony provides a session service that you can use to store information
+about the user between requests. Session storage and other configuration can
+be controlled under the :ref:`framework.session configuration `.
- .. code-block:: xml
+First, activate the session by uncommenting the ``session`` key in ``config/packages/framework.yaml``:
-
-
-
+.. code-block:: diff
-
-
-
-
-
-
- .. code-block:: php
+ # config/packages/framework.yaml
+ framework:
+ # ...
- // config/packages/framework.php
- $container->loadFromExtension('framework', array(
- 'session' => array(
- // ...
- 'handler_id' => null,
- ),
- ));
+ - #session:
+ - # # The native PHP session handler will be used
+ - # handler_id: ~
+ + session:
+ + # The native PHP session handler will be used
+ + handler_id: ~
+ # ...
-To retrieve the session, add the :class:`Symfony\\Component\\HttpFoundation\\Session\\SessionInterface`
-type-hint to your argument and Symfony will provide you with a session::
+To get the session, add an argument and type-hint it with
+:class:`Symfony\\Component\\HttpFoundation\\Session\\SessionInterface`::
use Symfony\Component\HttpFoundation\Session\SessionInterface;
@@ -511,12 +431,16 @@ type-hint to your argument and Symfony will provide you with a session::
$filters = $session->get('filters', array());
}
+.. versionadded:: 3.3
+ The ability to request a ``Session`` instance in controllers was introduced
+ in Symfony 3.3.
+
Stored attributes remain in the session for the remainder of that user's session.
.. tip::
Every ``SessionInterface`` implementation is supported. If you have your
- own implementation, type-hint this in the arguments instead.
+ own implementation, type-hint this in the argument instead.
For more info, see :doc:`/session`.
@@ -603,11 +527,9 @@ read any flash messages from the session using ``app.flashes()``:
-.. note::
-
- It's common to use ``notice``, ``warning`` and ``error`` as the keys of the
- different types of flash messages, but you can use any key that fits your
- needs.
+It's common to use ``notice``, ``warning`` and ``error`` as the keys of the
+different types of flash messages, but you can use any key that fits your
+needs.
.. tip::
@@ -623,7 +545,7 @@ read any flash messages from the session using ``app.flashes()``:
The Request and Response Object
-------------------------------
-As mentioned :ref:`earlier `, the framework will
+As mentioned :ref:`earlier `, Symfony will
pass the ``Request`` object to any controller argument that is type-hinted with
the ``Request`` class::
@@ -662,10 +584,7 @@ some nice methods for getting and setting response headers. The header names are
normalized so that using ``Content-Type`` is equivalent to ``content-type`` or even
``content_type``.
-The only requirement for a controller is to return a ``Response`` object.
-The :class:`Symfony\\Component\\HttpFoundation\\Response` class is an
-abstraction around the HTTP response - the text-based message filled with
-headers and content that's sent back to the client::
+The only requirement for a controller is to return a ``Response`` object::
use Symfony\Component\HttpFoundation\Response;
@@ -676,26 +595,15 @@ headers and content that's sent back to the client::
$response = new Response('');
$response->headers->set('Content-Type', 'text/css');
-There are special classes that make certain kinds of responses easier:
-
-* For files, there is :class:`Symfony\\Component\\HttpFoundation\\BinaryFileResponse`.
- See :ref:`component-http-foundation-serving-files`.
-
-* For streamed responses, there is
- :class:`Symfony\\Component\\HttpFoundation\\StreamedResponse`.
- See :ref:`streaming-response`.
+There are special classes that make certain kinds of responses easier. Some of these
+are mentioned below. To learn more about the ``Request`` and ``Response`` (and special
+``Response`` classes), see the :ref:`HttpFoundation component documentation `.
-.. seealso::
+Returning JSON Response
+~~~~~~~~~~~~~~~~~~~~~~~
- Now that you know the basics you can continue your research on Symfony
- ``Request`` and ``Response`` object in the
- :ref:`HttpFoundation component documentation `.
-
-JSON Helper
-~~~~~~~~~~~
-
-To return JSON from a controller, use the ``json()`` helper method on the base controller.
-This returns a special ``JsonResponse`` object that encodes the data automatically::
+To return JSON from a controller, use the ``json()`` helper method. This returns a
+special ``JsonResponse`` object that encodes the data automatically::
// ...
public function indexAction()
@@ -708,11 +616,11 @@ This returns a special ``JsonResponse`` object that encodes the data automatical
}
If the :doc:`serializer service ` is enabled in your
-application, contents passed to ``json()`` are encoded with it. Otherwise,
+application, it will be used to serialize the data to JSON. Otherwise,
the :phpfunction:`json_encode` function is used.
-File helper
-~~~~~~~~~~~
+Streaming File Responses
+~~~~~~~~~~~~~~~~~~~~~~~~
You can use the :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::file`
helper to serve a file from inside a controller::
diff --git a/page_creation.rst b/page_creation.rst
index 3f198eda84e..34251dad928 100644
--- a/page_creation.rst
+++ b/page_creation.rst
@@ -89,6 +89,8 @@ to creating a page?
return a ``Response`` object. You'll learn more about :doc:`controllers `
in their own section, including how to return JSON responses.
+.. _annotation-routes:
+
Annotation Routes
-----------------
@@ -164,6 +166,14 @@ To get a list of *all* of the routes in your system, use the ``debug:router`` co
$ php bin/console debug:router
+You should see your *one* route so far:
+
+================== ======== ======== ====== ===============
+ Name Method Scheme Host Path
+================== ======== ======== ====== ===============
+ app_lucky_number ANY ANY ANY /lucky/number
+================== ======== ======== ====== ===============
+
You'll learn about many more commands as you continue!
The Web Debug Toolbar: Debugging Dream
@@ -201,15 +211,17 @@ First, install Twig:
$ composer require twig
Second, make sure that ``LuckyController`` extends Symfony's base
-:class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` class::
+:class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` class:
+
+.. code-block:: diff
// src/Controller/LuckyController.php
// ...
- // --> add this new use statement
- use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+ + use Symfony\Bundle\FrameworkBundle\Controller\Controller;
- class LuckyController extends Controller
+ - class LuckyController
+ + class LuckyController extends Controller
{
// ...
}
@@ -266,8 +278,8 @@ project:
``src/``
All your PHP code lives here.
-99% of the time, you'll be working in ``src/`` (PHP files) or ``config/`` (everything
-else). As you keep reading, you'll learn what can be done inside each of these.
+Most of the time, you'll be working in ``src/`` (PHP files) or ``config/`` As you
+keep reading, you'll learn what can be done inside each of these.
So what about the other directories in the project?
@@ -287,6 +299,9 @@ So what about the other directories in the project?
This is the document root for your project: you put any publicly accessible files
here.
+And when you install new packages, new directories will be created automatically
+when needed.
+
What's Next?
------------
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index fdb8b257711..df49de99512 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -688,6 +688,8 @@ The value can be one of:
``true`` is recommended in the development environment, while ``false``
or ``null`` might be preferred in production.
+.. _config-framework-session:
+
session
~~~~~~~
diff --git a/routing.rst b/routing.rst
index 843cd507808..732c847c5be 100644
--- a/routing.rst
+++ b/routing.rst
@@ -4,33 +4,25 @@
Routing
=======
-Beautiful URLs are an absolute must for any serious web application. This
-means leaving behind ugly URLs like ``index.php?article_id=57`` in favor
-of something like ``/read/intro-to-symfony``.
+Beautiful URLs are a must for any serious web application. This means leaving behind
+ugly URLs like ``index.php?article_id=57`` in favor of something like ``/read/intro-to-symfony``.
Having flexibility is even more important. What if you need to change the
-URL of a page from ``/blog`` to ``/news``? How many links should you need to
+URL of a page from ``/blog`` to ``/news``? How many links would you need to
hunt down and update to make the change? If you're using Symfony's router,
the change is simple.
-The Symfony router lets you define creative URLs that you map to different
-areas of your application. By the end of this article, you'll be able to:
-
-* Create complex routes that map to controllers
-* Generate URLs inside templates and controllers
-* Load routing resources from bundles (or anywhere else)
-* Debug your routes
-
.. index::
single: Routing; Basics
-Routing Examples
-----------------
+.. _routing-creating-routes:
+
+Creating Routes
+---------------
-A *route* is a map from a URL path to a controller. For example, suppose
-you want to match any URL like ``/blog/my-post`` or ``/blog/all-about-symfony``
-and send it to a controller that can look up and render that blog entry.
-The route is simple:
+A *route* is a map from a URL path to a controller. Suppose you want one route that
+matches ``/blog`` exactly and another more dynamic route that can match *any* URL
+like ``/blog/my-post`` or ``/blog/all-about-symfony``::
.. configuration-block::
@@ -49,7 +41,7 @@ The route is simple:
*
* @Route("/blog", name="blog_list")
*/
- public function listAction()
+ public function list()
{
// ...
}
@@ -59,7 +51,7 @@ The route is simple:
*
* @Route("/blog/{slug}", name="blog_show")
*/
- public function showAction($slug)
+ public function show($slug)
{
// $slug will equal the dynamic part of the URL
// e.g. at /blog/yay-routing, then $slug='yay-routing'
@@ -73,11 +65,11 @@ The route is simple:
# config/routes.yaml
blog_list:
path: /blog
- defaults: { _controller: AppBundle:Blog:list }
+ controller: App\Controller\BlogController::list
blog_show:
path: /blog/{slug}
- defaults: { _controller: AppBundle:Blog:show }
+ controller: App\Controller\BlogController::show
.. code-block:: xml
@@ -89,11 +81,11 @@ The route is simple:
http://symfony.com/schema/routing/routing-1.0.xsd">
- AppBundle:Blog:list
+ App\Controller\BlogController::list
- AppBundle:Blog:show
+ App\Controller\BlogController::show
@@ -102,25 +94,26 @@ The route is simple:
// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
+ use App\Controller\BlogController;
$collection = new RouteCollection();
$collection->add('blog_list', new Route('/blog', array(
- '_controller' => 'AppBundle:Blog:list',
+ '_controller' => [BlogController::class, 'list']
)));
$collection->add('blog_show', new Route('/blog/{slug}', array(
- '_controller' => 'AppBundle:Blog:show',
+ '_controller' => [BlogController::class, 'show']
)));
return $collection;
Thanks to these two routes:
-* If the user goes to ``/blog``, the first route is matched and ``listAction()``
+* If the user goes to ``/blog``, the first route is matched and ``list()``
is executed;
-* If the user goes to ``/blog/*``, the second route is matched and ``showAction()``
+* If the user goes to ``/blog/*``, the second route is matched and ``show()``
is executed. Because the route path is ``/blog/{slug}``, a ``$slug`` variable is
- passed to ``showAction()`` matching that value. For example, if the user goes to
+ passed to ``show()`` matching that value. For example, if the user goes to
``/blog/yay-routing``, then ``$slug`` will equal ``yay-routing``.
Whenever you have a ``{placeholder}`` in your route path, that portion becomes a
@@ -128,25 +121,14 @@ wildcard: it matches *any* value. Your controller can now *also* have an argumen
called ``$placeholder`` (the wildcard and argument names *must* match).
Each route also has an internal name: ``blog_list`` and ``blog_show``. These can
-be anything (as long as each is unique) and don't have any meaning yet.
-Later, you'll use it to generate URLs.
+be anything (as long as each is unique) and don't have any meaning yet. You'll
+use them later to :ref:`generate URLs `.
.. sidebar:: Routing in Other Formats
The ``@Route`` above each method is called an *annotation*. If you'd rather
- configure your routes in YAML, XML or PHP, that's no problem!
-
- In these formats, the ``_controller`` "defaults" value is a special key that
- tells Symfony which controller should be executed when a URL matches this route.
- The ``_controller`` string is called the
- :ref:`logical name `. It follows a pattern that
- points to a specific PHP class and method, in this case the
- ``App\Controller\BlogController::listAction`` and
- ``App\Controller\BlogController::showAction`` methods.
-
-This is the goal of the Symfony router: to map the URL of a request to a
-controller. Along the way, you'll learn all sorts of tricks that make mapping
-even the most complex URLs easy.
+ configure your routes in YAML, XML or PHP, that's no problem! Just create a
+ new routing file (e.g. ``routes.xml``) and Symfony will automatically use it.
.. _routing-requirements:
@@ -181,7 +163,7 @@ To fix this, add a *requirement* that the ``{page}`` wildcard can *only* match n
/**
* @Route("/blog/{page}", name="blog_list", requirements={"page": "\d+"})
*/
- public function listAction($page)
+ public function list($page)
{
// ...
}
@@ -189,7 +171,7 @@ To fix this, add a *requirement* that the ``{page}`` wildcard can *only* match n
/**
* @Route("/blog/{slug}", name="blog_show")
*/
- public function showAction($slug)
+ public function show($slug)
{
// ...
}
@@ -200,7 +182,7 @@ To fix this, add a *requirement* that the ``{page}`` wildcard can *only* match n
# config/routes.yaml
blog_list:
path: /blog/{page}
- defaults: { _controller: AppBundle:Blog:list }
+ controller: App\Controller\BlogController::list
requirements:
page: '\d+'
@@ -217,7 +199,7 @@ To fix this, add a *requirement* that the ``{page}`` wildcard can *only* match n
http://symfony.com/schema/routing/routing-1.0.xsd">
- AppBundle:Blog:list
+ App\Controller\BlogController::list
\d+
@@ -229,10 +211,11 @@ To fix this, add a *requirement* that the ``{page}`` wildcard can *only* match n
// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
+ use App\Controller\BlogController;
$collection = new RouteCollection();
$collection->add('blog_list', new Route('/blog/{page}', array(
- '_controller' => 'AppBundle:Blog:list',
+ '_controller' => [BlogController::class, 'list'],
), array(
'page' => '\d+'
)));
@@ -279,7 +262,7 @@ So how can you make ``blog_list`` once again match when the user visits
/**
* @Route("/blog/{page}", name="blog_list", requirements={"page": "\d+"})
*/
- public function listAction($page = 1)
+ public function list($page = 1)
{
// ...
}
@@ -290,7 +273,9 @@ So how can you make ``blog_list`` once again match when the user visits
# config/routes.yaml
blog_list:
path: /blog/{page}
- defaults: { _controller: AppBundle:Blog:list, page: 1 }
+ controller: App\Controller\BlogController::list
+ defaults:
+ page: 1
requirements:
page: '\d+'
@@ -307,7 +292,7 @@ So how can you make ``blog_list`` once again match when the user visits
http://symfony.com/schema/routing/routing-1.0.xsd">
- AppBundle:Blog:list
+ App\Controller\BlogController::list
1
\d+
@@ -321,12 +306,13 @@ So how can you make ``blog_list`` once again match when the user visits
// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
+ use App\Controller\BlogController;
$collection = new RouteCollection();
$collection->add('blog_list', new Route(
'/blog/{page}',
array(
- '_controller' => 'AppBundle:Blog:list',
+ '_controller' => [BlogController::class, 'list'],
'page' => 1,
),
array(
@@ -372,7 +358,7 @@ With all of this in mind, check out this advanced example:
* }
* )
*/
- public function showAction($_locale, $year, $slug)
+ public function show($_locale, $year, $slug)
{
}
}
@@ -382,7 +368,9 @@ With all of this in mind, check out this advanced example:
# config/routes.yaml
article_show:
path: /articles/{_locale}/{year}/{slug}.{_format}
- defaults: { _controller: AppBundle:Article:show, _format: html }
+ controller: App\Controller\ArticleController::show
+ defaults:
+ _format: html
requirements:
_locale: en|fr
_format: html|rss
@@ -400,7 +388,7 @@ With all of this in mind, check out this advanced example:
- AppBundle:Article:show
+ App\Controller\ArticleController::show
html
en|fr
html|rss
@@ -414,12 +402,13 @@ With all of this in mind, check out this advanced example:
// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
+ use App\Controller\ArticleController;
$collection = new RouteCollection();
$collection->add(
'article_show',
new Route('/articles/{_locale}/{year}/{slug}.{_format}', array(
- '_controller' => 'AppBundle:Article:show',
+ '_controller' => [ArticleController::class, 'show'],
'_format' => 'html',
), array(
'_locale' => 'en|fr',
@@ -449,16 +438,7 @@ a slash. URLs matching this route might look like:
Ultimately, the request format is used for such things as setting the
``Content-Type`` of the response (e.g. a ``json`` request format translates
- into a ``Content-Type`` of ``application/json``). It can also be used in the
- controller to render a different template for each value of ``_format``.
- The ``_format`` parameter is a very powerful way to render the same content
- in different formats.
-
- In Symfony versions previous to 3.0, it is possible to override the request
- format by adding a query parameter named ``_format`` (for example:
- ``/foo/bar?_format=json``). Relying on this behavior not only is considered
- a bad practice but it will complicate the upgrade of your applications to
- Symfony 3.
+ into a ``Content-Type`` of ``application/json``).
.. note::
@@ -500,44 +480,9 @@ that are special: each adds a unique piece of functionality inside your applicat
Controller Naming Pattern
-------------------------
-If you use YAML, XML or PHP route configuration, then each route must have a
-``_controller`` parameter, which dictates which controller should be executed when
-that route is matched. This parameter uses a simple string pattern called the
-*logical controller name*, which Symfony maps to a specific PHP method and class.
-The pattern has three parts, each separated by a colon:
-
- **bundle**:**controller**:**action**
-
-For example, a ``_controller`` value of ``AppBundle:Blog:show`` means:
-
-============= ================== ================
-Bundle Controller Class Method Name
-============= ================== ================
-``AppBundle`` ``BlogController`` ``showAction()``
-============= ================== ================
-
-The controller might look like this::
-
- // src/Controller/BlogController.php
- namespace App\Controller;
-
- use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-
- class BlogController extends Controller
- {
- public function showAction($slug)
- {
- // ...
- }
- }
-
-Notice that Symfony adds the string ``Controller`` to the class name (``Blog``
-=> ``BlogController``) and ``Action`` to the method name (``show`` => ``showAction()``).
-
-You could also refer to this controller using its fully-qualified class name
-and method: ``App\Controller\BlogController::showAction``. But if you
-follow some simple conventions, the logical name is more concise and allows
-more flexibility.
+The ``controller`` value in your routes has a very simple format ``CONTROLLER_CLASS::METHOD``.
+If your controller is registered as a service, you can also use just one colon separator
+(e.g. ``service_name:index``).
.. tip::
@@ -545,75 +490,16 @@ more flexibility.
you do not have to pass the method name, but can just use the fully qualified class name (e.g.
``App\Controller\BlogController``).
-.. note::
-
- In addition to using the logical name or the fully-qualified class name,
- Symfony supports a third way of referring to a controller. This method
- uses just one colon separator (e.g. ``service_name:indexAction``) and
- refers to the controller as a service (see :doc:`/controller/service`).
-
-.. index::
- single: Routing; Creating routes
-
-.. _routing-creating-routes:
-
-Loading Routes
---------------
-
-Symfony loads all the routes for your application from a *single* routing configuration
-file: ``config/routes.yaml``. But from inside of this file, you can load any
-*other* routing files you want. In fact, by default, Symfony loads annotation route
-configuration from your AppBundle's ``Controller/`` directory, which is how Symfony
-sees our annotation routes:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # config/routes.yaml
- app:
- resource: "@AppBundle/Controller/"
- type: annotation
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
- .. code-block:: php
-
- // config/routes.php
- use Symfony\Component\Routing\RouteCollection;
-
- $collection = new RouteCollection();
- $collection->addCollection(
- // second argument is the type, which is required to enable
- // the annotation reader for this resource
- $loader->import("@AppBundle/Controller/", "annotation")
- );
-
- return $collection;
-
-For more details on loading routes, including how to prefix the paths of loaded routes,
-see :doc:`/routing/external_resources`.
-
.. index::
single: Routing; Generating URLs
+.. _routing-generate:
+
Generating URLs
---------------
-The routing system should also be used to generate URLs. In reality, routing
-is a bidirectional system: mapping the URL to a controller and
-a route back to a URL.
+The routing system can also generate URLs. In reality, routing is a bidirectional
+system: mapping the URL to a controller and also a route back to a URL.
To generate a URL, you need to specify the name of the route (e.g. ``blog_show``)
and any wildcards (e.g. ``slug = my-blog-post``) used in the path for that
@@ -621,7 +507,7 @@ route. With this information, any URL can easily be generated::
class MainController extends Controller
{
- public function showAction($slug)
+ public function show($slug)
{
// ...
@@ -633,16 +519,31 @@ route. With this information, any URL can easily be generated::
}
}
-.. note::
+If you need to generate a URL from a service, type-hint the :class:`Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface`
+service::
- The ``generateUrl()`` method defined in the base
- :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` class is
- just a shortcut for this code::
+ // src/Service/SomeService.php
- $url = $this->container->get('router')->generate(
- 'blog_show',
- array('slug' => 'my-blog-post')
- );
+ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+
+ class SomeService
+ {
+ private $router;
+
+ public function __construct(UrlGeneratorInterface $router)
+ {
+ $this->router = $router;
+ }
+
+ public function someMethod()
+ {
+ $url = $this->router->generate(
+ 'blog_show',
+ array('slug' => 'my-blog-post')
+ );
+ // ...
+ }
+ }
.. index::
single: Routing; Generating URLs in a template
@@ -693,12 +594,12 @@ Troubleshooting
Here are some common errors you might see while working with routing:
- Controller "App\Controller\BlogController::showAction()" requires that you
+ Controller "App\Controller\BlogController::show()" requires that you
provide a value for the "$slug" argument.
This happens when your controller method has an argument (e.g. ``$slug``)::
- public function showAction($slug)
+ public function show($slug)
{
// ..
}
@@ -729,15 +630,6 @@ one for each supported language; or use any of the bundles created by the
community to implement this feature, such as `JMSI18nRoutingBundle`_ and
`BeSimpleI18nRoutingBundle`_.
-Summary
--------
-
-Routing is a system for mapping the URL of incoming requests to the controller
-function that should be called to process the request. It both allows you
-to specify beautiful URLs and keeps the functionality of your application
-decoupled from those URLs. Routing is a bidirectional mechanism, meaning that it
-should also be used to generate URLs.
-
Keep Going!
-----------