@@ -11,7 +11,7 @@ a serialized JSON array, an image, a redirect, a 404 error or anything else
11
11
you can dream up. The controller contains whatever arbitrary logic *your
12
12
application * needs to render the content of a page.
13
13
14
- To see how simple this is, let's look at a Symfony2 controller in action.
14
+ See how simple this is by looking at a Symfony2 controller in action.
15
15
The following controller would render a page that simply prints ``Hello world! ``::
16
16
17
17
use Symfony\Component\HttpFoundation\Response;
@@ -73,7 +73,7 @@ maps a URL to that controller (#2).
73
73
.. note ::
74
74
75
75
Though similarly named, a "front controller" is different from the
76
- "controllers" we'll talk about in this chapter. A front controller
76
+ "controllers" talked about in this chapter. A front controller
77
77
is a short PHP file that lives in your web directory and through which
78
78
all requests are directed. A typical application will have a production
79
79
front controller (e.g. ``app.php ``) and a development front controller
@@ -102,7 +102,7 @@ a controller object. Controllers are also called *actions*.
102
102
{
103
103
public function indexAction($name)
104
104
{
105
- return new Response('<html ><body >Hello '.$name.'!</body ></html >');
105
+ return new Response('<html ><body >Hello '.$name.'!</body ></html >');
106
106
}
107
107
}
108
108
@@ -115,11 +115,11 @@ a controller object. Controllers are also called *actions*.
115
115
will house several controllers/actions (e.g. ``updateAction ``, ``deleteAction ``,
116
116
etc).
117
117
118
- This controller is pretty straightforward, but let's walk through it :
118
+ This controller is pretty straightforward:
119
119
120
120
* *line 4 *: Symfony2 takes advantage of PHP 5.3 namespace functionality to
121
121
namespace the entire controller class. The ``use `` keyword imports the
122
- ``Response `` class, which our controller must return.
122
+ ``Response `` class, which the controller must return.
123
123
124
124
* *line 6 *: The class name is the concatenation of a name for the controller
125
125
class (i.e. ``Hello ``) and the word ``Controller ``. This is a convention
@@ -141,7 +141,7 @@ Mapping a URL to a Controller
141
141
-----------------------------
142
142
143
143
The new controller returns a simple HTML page. To actually view this page
144
- in your browser, you need to create a route, which maps a specific URL pattern
144
+ in your browser, you need to create a route, which maps a specific URL path
145
145
to the controller:
146
146
147
147
.. configuration-block ::
@@ -150,15 +150,22 @@ to the controller:
150
150
151
151
# app/config/routing.yml
152
152
hello :
153
- pattern : /hello/{name}
154
- defaults : { _controller: AcmeHelloBundle:Hello:index }
153
+ path : /hello/{name}
154
+ defaults : { _controller: AcmeHelloBundle:Hello:index }
155
155
156
156
.. code-block :: xml
157
157
158
158
<!-- app/config/routing.xml -->
159
- <route id =" hello" pattern =" /hello/{name}" >
160
- <default key =" _controller" >AcmeHelloBundle:Hello:index</default >
161
- </route >
159
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
160
+ <routes xmlns =" http://symfony.com/schema/routing"
161
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
162
+ xsi : schemaLocation =" http://symfony.com/schema/routing
163
+ http://symfony.com/schema/routing/routing-1.0.xsd" >
164
+
165
+ <route id =" hello" path =" /hello/{name}" >
166
+ <default key =" _controller" >AcmeHelloBundle:Hello:index</default >
167
+ </route >
168
+ </routes >
162
169
163
170
.. code-block :: php
164
171
@@ -189,7 +196,7 @@ see :ref:`controller-string-syntax`.
189
196
190
197
.. tip ::
191
198
192
- You can learn much more about the routing system in the :doc: `Routing chapter</book/routing> `.
199
+ You can learn much more about the routing system in the :doc: `Routing chapter </book/routing >`.
193
200
194
201
.. index ::
195
202
single: Controller; Controller arguments
@@ -202,11 +209,8 @@ Route Parameters as Controller Arguments
202
209
You already know that the ``_controller `` parameter ``AcmeHelloBundle:Hello:index ``
203
210
refers to a ``HelloController::indexAction() `` method that lives inside the
204
211
``AcmeHelloBundle `` bundle. What's more interesting is the arguments that are
205
- passed to that method:
206
-
207
- .. code-block :: php
212
+ passed to that method::
208
213
209
- <?php
210
214
// src/Acme/HelloBundle/Controller/HelloController.php
211
215
namespace Acme\HelloBundle\Controller;
212
216
@@ -221,7 +225,7 @@ passed to that method:
221
225
}
222
226
223
227
The controller has a single argument, ``$name ``, which corresponds to the
224
- ``{name} `` parameter from the matched route (``ryan `` in our example). In
228
+ ``{name} `` parameter from the matched route (``ryan `` in the example). In
225
229
fact, when executing your controller, Symfony2 matches each argument of
226
230
the controller with a parameter from the matched route. Take the following
227
231
example:
@@ -232,16 +236,23 @@ example:
232
236
233
237
# app/config/routing.yml
234
238
hello :
235
- pattern : /hello/{first_name}/{last_name}
236
- defaults : { _controller: AcmeHelloBundle:Hello:index, color: green }
239
+ path : /hello/{first_name}/{last_name}
240
+ defaults : { _controller: AcmeHelloBundle:Hello:index, color: green }
237
241
238
242
.. code-block :: xml
239
243
240
244
<!-- app/config/routing.xml -->
241
- <route id =" hello" pattern =" /hello/{first_name}/{last_name}" >
242
- <default key =" _controller" >AcmeHelloBundle:Hello:index</default >
243
- <default key =" color" >green</default >
244
- </route >
245
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
246
+ <routes xmlns =" http://symfony.com/schema/routing"
247
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
248
+ xsi : schemaLocation =" http://symfony.com/schema/routing
249
+ http://symfony.com/schema/routing/routing-1.0.xsd" >
250
+
251
+ <route id =" hello" path =" /hello/{first_name}/{last_name}" >
252
+ <default key =" _controller" >AcmeHelloBundle:Hello:index</default >
253
+ <default key =" color" >green</default >
254
+ </route >
255
+ </routes >
245
256
246
257
.. code-block :: php
247
258
@@ -335,6 +346,14 @@ working with forms, for example::
335
346
.. index ::
336
347
single: Controller; Base controller class
337
348
349
+ Creating Static Pages
350
+ ---------------------
351
+
352
+ You can create a static page without even creating a controller (only a route
353
+ and template are needed).
354
+
355
+ Use it! See :doc: `/cookbook/templating/render_without_controller `.
356
+
338
357
The Base Controller Class
339
358
-------------------------
340
359
@@ -344,9 +363,7 @@ access to any resource it might need. By extending this ``Controller`` class,
344
363
you can take advantage of several helper methods.
345
364
346
365
Add the ``use `` statement atop the ``Controller `` class and then modify the
347
- ``HelloController `` to extend it:
348
-
349
- .. code-block :: php
366
+ ``HelloController `` to extend it::
350
367
351
368
// src/Acme/HelloBundle/Controller/HelloController.php
352
369
namespace Acme\HelloBundle\Controller;
@@ -358,7 +375,7 @@ Add the ``use`` statement atop the ``Controller`` class and then modify the
358
375
{
359
376
public function indexAction($name)
360
377
{
361
- return new Response('<html ><body >Hello '.$name.'!</body ></html >');
378
+ return new Response('<html><body>Hello '.$name.'!</body></html>');
362
379
}
363
380
}
364
381
@@ -375,13 +392,14 @@ itself.
375
392
376
393
Extending the base class is *optional * in Symfony; it contains useful
377
394
shortcuts but nothing mandatory. You can also extend
378
- `` Symfony\Component\DependencyInjection\ContainerAware ` `. The service
395
+ :class: ` Symfony\\ Component\\ DependencyInjection\\ ContainerAware `. The service
379
396
container object will then be accessible via the ``container `` property.
380
397
381
398
.. note ::
382
399
383
- You can also define your :doc: `Controllers as Services
384
- </cookbook/controller/service>`.
400
+ You can also define your :doc: `Controllers as Services </cookbook/controller/service >`.
401
+ This is optional, but can give you more control over the exact dependencies
402
+ that are injected into your controllers.
385
403
386
404
.. index ::
387
405
single: Controller; Common tasks
@@ -422,9 +440,7 @@ perform a 301 (permanent) redirect, modify the second argument::
422
440
.. tip ::
423
441
424
442
The ``redirect() `` method is simply a shortcut that creates a ``Response ``
425
- object that specializes in redirecting the user. It's equivalent to:
426
-
427
- .. code-block :: php
443
+ object that specializes in redirecting the user. It's equivalent to::
428
444
429
445
use Symfony\Component\HttpFoundation\RedirectResponse;
430
446
@@ -436,7 +452,8 @@ perform a 301 (permanent) redirect, modify the second argument::
436
452
Forwarding
437
453
~~~~~~~~~~
438
454
439
- You can also easily forward to another controller internally with the ``forward() ``
455
+ You can also easily forward to another controller internally with the
456
+ :method: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller::forward `
440
457
method. Instead of redirecting the user's browser, it makes an internal sub-request,
441
458
and calls the specified controller. The ``forward() `` method returns the ``Response ``
442
459
object that's returned from that controller::
@@ -445,7 +462,7 @@ object that's returned from that controller::
445
462
{
446
463
$response = $this->forward('AcmeHelloBundle:Hello:fancy', array(
447
464
'name' => $name,
448
- 'color' => 'green'
465
+ 'color' => 'green',
449
466
));
450
467
451
468
// ... further modify the response or return it directly
@@ -476,14 +493,22 @@ value to each variable.
476
493
477
494
Like other base ``Controller `` methods, the ``forward `` method is just
478
495
a shortcut for core Symfony2 functionality. A forward can be accomplished
479
- directly via the ``http_kernel `` service. A forward returns a ``Response ``
480
- object::
496
+ directly by duplicating the current request. When this
497
+ :ref: `sub request <http-kernel-sub-requests >` is executed via the ``http_kernel ``
498
+ service the ``HttpKernel `` returns a ``Response `` object::
499
+
500
+ use Symfony\Component\HttpKernel\HttpKernelInterface;
501
+
502
+ $path = array(
503
+ '_controller' => 'AcmeHelloBundle:Hello:fancy',
504
+ 'name' => $name,
505
+ 'color' => 'green',
506
+ );
507
+ $request = $this->container->get('request');
508
+ $subRequest = $request->duplicate(array(), null, $path);
481
509
482
510
$httpKernel = $this->container->get('http_kernel');
483
- $response = $httpKernel->forward('AcmeHelloBundle:Hello:fancy', array(
484
- 'name' => $name,
485
- 'color' => 'green',
486
- ));
511
+ $response = $httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
487
512
488
513
.. index ::
489
514
single: Controller; Rendering templates
@@ -498,36 +523,57 @@ that's responsible for generating the HTML (or other format) for the controller.
498
523
The ``renderView() `` method renders a template and returns its content. The
499
524
content from the template can be used to create a ``Response `` object::
500
525
501
- $content = $this->renderView('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));
526
+ use Symfony\Component\HttpFoundation\Response;
527
+
528
+ $content = $this->renderView(
529
+ 'AcmeHelloBundle:Hello:index.html.twig',
530
+ array('name' => $name)
531
+ );
502
532
503
533
return new Response($content);
504
534
505
535
This can even be done in just one step with the ``render() `` method, which
506
536
returns a ``Response `` object containing the content from the template::
507
537
508
- return $this->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));
538
+ return $this->render(
539
+ 'AcmeHelloBundle:Hello:index.html.twig',
540
+ array('name' => $name)
541
+ );
509
542
510
543
In both cases, the ``Resources/views/Hello/index.html.twig `` template inside
511
544
the ``AcmeHelloBundle `` will be rendered.
512
545
513
546
The Symfony templating engine is explained in great detail in the
514
547
:doc: `Templating </book/templating >` chapter.
515
548
549
+ .. tip ::
550
+
551
+ You can even avoid calling the ``render `` method by using the ``@Template ``
552
+ annotation. See the
553
+ :doc: `FrameworkExtraBundle documentation </bundles/SensioFrameworkExtraBundle/annotations/view >`
554
+ more details.
555
+
516
556
.. tip ::
517
557
518
558
The ``renderView `` method is a shortcut to direct use of the ``templating ``
519
559
service. The ``templating `` service can also be used directly::
520
560
521
561
$templating = $this->get('templating');
522
- $content = $templating->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));
562
+ $content = $templating->render(
563
+ 'AcmeHelloBundle:Hello:index.html.twig',
564
+ array('name' => $name)
565
+ );
523
566
524
567
.. note ::
525
568
526
569
It is possible to render templates in deeper subdirectories as well, however
527
570
be careful to avoid the pitfall of making your directory structure unduly
528
571
elaborate::
529
572
530
- $templating->render('AcmeHelloBundle:Hello/Greetings:index.html.twig', array('name' => $name));
573
+ $templating->render(
574
+ 'AcmeHelloBundle:Hello/Greetings:index.html.twig',
575
+ array('name' => $name)
576
+ );
531
577
// index.html.twig found in Resources/views/Hello/Greetings is rendered.
532
578
533
579
.. index ::
@@ -644,7 +690,10 @@ For example, imagine you're processing a form submit::
644
690
if ($form->isValid()) {
645
691
// do some sort of processing
646
692
647
- $this->get('session')->getFlashBag()->add('notice', 'Your changes were saved!');
693
+ $this->get('session')->getFlashBag()->add(
694
+ 'notice',
695
+ 'Your changes were saved!'
696
+ );
648
697
649
698
return $this->redirect($this->generateUrl(...));
650
699
}
@@ -669,7 +718,7 @@ the ``notice`` message:
669
718
</div>
670
719
{% endfor %}
671
720
672
- .. code-block :: php
721
+ .. code-block :: html+ php
673
722
674
723
<?php foreach ($view['session']->getFlashBag()->get('notice') as $message): ?>
675
724
<div class="flash-notice">
@@ -692,6 +741,8 @@ The only requirement for a controller is to return a ``Response`` object. The
692
741
abstraction around the HTTP response - the text-based message filled with HTTP
693
742
headers and content that's sent back to the client::
694
743
744
+ use Symfony\Component\HttpFoundation\Response;
745
+
695
746
// create a simple Response with a 200 status code (the default)
696
747
$response = new Response('Hello '.$name, 200);
697
748
@@ -707,6 +758,15 @@ headers and content that's sent back to the client::
707
758
header names are normalized so that using ``Content-Type `` is equivalent
708
759
to ``content-type `` or even ``content_type ``.
709
760
761
+ .. tip ::
762
+
763
+ There are also special classes to make certain kinds of responses easier:
764
+
765
+ - For JSON, there is :class: `Symfony\\ Component\\ HttpFoundation\\ JsonResponse `.
766
+ See :ref: `component-http-foundation-json-response `.
767
+ - For files, there is :class: `Symfony\\ Component\\ HttpFoundation\\ BinaryFileResponse `.
768
+ See :ref: `component-http-foundation-serving-files `.
769
+
710
770
.. index ::
711
771
single: Controller; Request object
712
772
0 commit comments