Skip to content

Commit 8793cb5

Browse files
committed
controller ch review, part 3
1 parent 032b167 commit 8793cb5

File tree

1 file changed

+88
-71
lines changed

1 file changed

+88
-71
lines changed

book/controller.rst

Lines changed: 88 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@ A great way to see the core functionality in action is to look in the
428428
.. index::
429429
single: Controller; Redirecting
430430

431+
.. _book-redirecting-users-browser:
432+
431433
Redirecting
432434
~~~~~~~~~~~
433435

@@ -675,13 +677,54 @@ read any flash messages from the session:
675677
.. index::
676678
single: Controller; Response object
677679

678-
The Response Object
679-
-------------------
680+
The Request and Response Object
681+
-------------------------------
682+
683+
As already mentioned a :ref:`little earlier <book-controller-request-argument>`,
684+
besides the values of the routing parameters, the controller has also access
685+
to the ``Request`` object. The framework injects the ``Request`` object
686+
in the controller if a variable is type-hinted with ``Request`` class::
687+
688+
use Symfony\Component\HttpFoundation\Request;
689+
690+
public function indexAction(Request $request)
691+
{
692+
$request->isXmlHttpRequest(); // is it an Ajax request?
693+
694+
$request->getPreferredLanguage(array('en', 'fr'));
695+
696+
// retrieve GET and POST variables respectively
697+
$request->query->get('page');
698+
$request->request->get('page');
680699

681-
The only requirement for a controller is to return a ``Response`` object. The
682-
:class:`Symfony\\Component\\HttpFoundation\\Response` class is an abstraction
683-
around the HTTP response: the text-based message filled with headers and
684-
content that's sent back to the client::
700+
// retrieve SERVER variables
701+
$request->server->get('HTTP_HOST');
702+
703+
// retrieves an instance of UploadedFile identified by foo
704+
$request->files->get('foo');
705+
706+
// retrieve a COOKIE value
707+
$request->cookies->get('PHPSESSID');
708+
709+
// retrieve an HTTP request header, with normalized, lowercase keys
710+
$request->headers->get('host');
711+
$request->headers->get('content_type');
712+
}
713+
714+
``Request`` class has several public properties via which information about the client
715+
request can be accessed. If you haven't already mastered HTTP fundamentals you
716+
can read about Symfony ``Request`` object in detail :ref:`here <book-request-object>`.
717+
718+
Like the ``Request``, the ``Response`` object has also a public ``headers`` property
719+
which is a :class:`Symfony\\Component\\HttpFoundation\\ResponseHeaderBag` instance.
720+
``ResponseHeaderBag`` instances have methods for getting and setting the response
721+
headers. The header names are normalized so that using ``Content-Type`` is equivalent
722+
to ``content-type`` or even ``content_type``.
723+
724+
The only requirement for a controller is to return a ``Response`` object.
725+
The :class:`Symfony\\Component\\HttpFoundation\\Response` class is an
726+
abstraction around the HTTP response - the text-based message filled with
727+
headers and content that's sent back to the client::
685728

686729
use Symfony\Component\HttpFoundation\Response;
687730

@@ -692,11 +735,6 @@ content that's sent back to the client::
692735
$response = new Response(json_encode(array('name' => $name)));
693736
$response->headers->set('Content-Type', 'application/json');
694737

695-
The ``headers`` property is a :class:`Symfony\\Component\\HttpFoundation\\HeaderBag`
696-
object and has some nice methods for getting and setting the headers. The
697-
header names are normalized so that using ``Content-Type`` is equivalent to
698-
``content-type`` or even ``content_type``.
699-
700738
There are also special classes to make certain kinds of responses easier:
701739

702740
* For JSON, there is :class:`Symfony\\Component\\HttpFoundation\\JsonResponse`.
@@ -705,65 +743,38 @@ There are also special classes to make certain kinds of responses easier:
705743
* For files, there is :class:`Symfony\\Component\\HttpFoundation\\BinaryFileResponse`.
706744
See :ref:`component-http-foundation-serving-files`.
707745

708-
* For streamed responses, there is :class:`Symfony\\Component\\HttpFoundation\\StreamedResponse`.
746+
* For streamed responses, there is
747+
:class:`Symfony\\Component\\HttpFoundation\\StreamedResponse`.
709748
See :ref:`streaming-response`.
710749

711750
.. seealso::
712751

713-
Don't worry! There is a lot more information about the Response object
714-
in the component documentation. See :ref:`component-http-foundation-response`.
715-
716-
.. index::
717-
single: Controller; Request object
718-
719-
The Request Object
720-
------------------
721-
722-
Besides the values of the routing placeholders, the controller also has access
723-
to the ``Request`` object. The framework injects the ``Request`` object in the
724-
controller if a variable is type-hinted with
725-
:class:`Symfony\\Component\\HttpFoundation\\Request`::
726-
727-
use Symfony\Component\HttpFoundation\Request;
728-
729-
public function indexAction(Request $request)
730-
{
731-
$request->isXmlHttpRequest(); // is it an Ajax request?
732-
733-
$request->getPreferredLanguage(array('en', 'fr'));
734-
735-
$request->query->get('page'); // get a $_GET parameter
736-
737-
$request->request->get('page'); // get a $_POST parameter
738-
}
739-
740-
Like the ``Response`` object, the request headers are stored in a ``HeaderBag``
741-
object and are easily accessible.
742-
743-
.. seealso::
744-
745-
Don't worry! There is a lot more information about the Request object
746-
in the component documentation. See :ref:`component-http-foundation-request`.
752+
Now that you know the basics you can continue your research on Symfony
753+
``Request`` and ``Response`` object in the
754+
:ref:`HttpFoundation component documentation <component-http-foundation-request>`.
747755

748756
Creating Static Pages
749757
---------------------
750758

751759
You can create a static page without even creating a controller (only a route
752-
and template are needed).
753-
754-
See :doc:`/cookbook/templating/render_without_controller`.
760+
and template are needed). See cookbook article
761+
:doc:`/cookbook/templating/render_without_controller`.
755762

756763
.. index::
757764
single: Controller; Forwarding
758765

759766
Forwarding to Another Controller
760767
--------------------------------
761768

762-
Though not very common, you can also forward to another controller internally
763-
with the :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::forward`
764-
method. Instead of redirecting the user's browser, it makes an internal sub-request,
765-
and calls the controller. The ``forward()`` method returns the ``Response``
766-
object that's returned from *that* controller::
769+
We already saw how to redirect the :ref:`user's browser <book-redirecting-users-browser>`
770+
to another page internally or to some external URL.
771+
772+
Though not very common, you can also forward to another controller
773+
internally with the basic ``Controller`` class method
774+
:method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::forward`.
775+
Instead of redirecting the user's browser, method makes an internal
776+
sub-request, and calls the defined controller. The ``forward()`` method returns
777+
the ``Response`` object that's returned from *that* controller::
767778

768779
public function indexAction($name)
769780
{
@@ -777,36 +788,42 @@ object that's returned from *that* controller::
777788
return $response;
778789
}
779790

780-
Notice that the ``forward()`` method uses a special string representation
781-
of the controller (see :ref:`controller-string-syntax`). In this case, the
782-
target controller function will be ``SomethingController::fancyAction()``
783-
inside the AppBundle. The array passed to the method becomes the arguments on
784-
the resulting controller. This same idea is used when embedding controllers
785-
into templates (see :ref:`templating-embedding-controller`). The target
786-
controller method would look something like this::
791+
The array passed to the method becomes the arguments on the resulting controller.
792+
The target controller method would look something like this::
787793

788794
public function fancyAction($name, $color)
789795
{
790796
// ... create and return a Response object
791797
}
792798

793-
Just like when creating a controller for a route, the order of the arguments of
794-
``fancyAction`` doesn't matter. Symfony matches the index key names (e.g.
795-
``name``) with the method argument names (e.g. ``$name``). If you change the
796-
order of the arguments, Symfony will still pass the correct value to each
797-
variable.
799+
.. sidebar:: Logical controller name
798800

799-
Checking the Validity of a CSRF Token
800-
-------------------------------------
801+
Notice that the ``forward()`` method uses a special string representation
802+
called *logical controller name* which, for example, looks like
803+
``AppBundle:Hello:index``. For more details on the controller format, read
804+
:ref:`controller-string-syntax` subtitle of the Routing chapter.
801805

802-
Sometimes you want to use CSRF protection in an action where you don't want to use a
803-
Symfony form.
806+
You can learn much more about the routing system in the
807+
:doc:`Routing chapter </book/routing>`.
808+
809+
Just like when creating a controller for a route, the order of the
810+
arguments of ``fancyAction()`` doesn't matter. Symfony matches the route
811+
placeholder names (e.g. ``{name}``) with the method argument names (e.g. ``$name``).
812+
If you change the order of the arguments, Symfony will still pass the correct
813+
value to each variable.
814+
815+
Checking the Validity of a CSRF Token inside Controller
816+
-------------------------------------------------------
817+
818+
Sometimes you want to use :ref:`CSRF protection <forms-csrf>` in a controller where
819+
you don't want to use a Symfony form.
804820

805821
If, for example, you're doing a DELETE action, you can use the
806-
:method:`Symfony\\Component\\Form\\Extension\\Csrf\\CsrfProvider\\CsrfProviderInterface::isCsrfTokenValid`
822+
:method:`Symfony\\Component\\Form\\Extension\\Csrf\\CsrfProvider\\SessionCsrfProvider::isCsrfTokenValid`
807823
method to check the CSRF token::
808824

809825
$csrf = $this->container->get('form.csrf_provider');
826+
810827
$intention = 'authenticate';
811828
$token = $csrf->generateCsrfToken($intention);
812829

0 commit comments

Comments
 (0)