The Quick Tour (Symfony 3.0)

Web Development Frameworks · course

Browse all développement web documents

The Quick Tour

Version: 3.0

generated on February 8, 2016

What could be better to make up your own mind than to try out Symfony yourself? Aside from

a little time, it will cost you nothing. Step by step you will explore the Symfony universe. Be

careful, Symfony can become addictive from the very first encounter!

The Quick Tour (3.0)

This work is licensed under the “Attribution-Share Alike 3.0 Unported” license (http://creativecommons.org/

licenses/by-sa/3.0/).

You are free to share (to copy, distribute and transmit the work), and to remix (to adapt the work) under the

following conditions:

• Attribution: You must attribute the work in the manner specified by the author or licensor (but

not in any way that suggests that they endorse you or your use of the work).

• Share Alike: If you alter, transform, or build upon this work, you may distribute the resulting work

only under the same, similar or a compatible license. For any reuse or distribution, you must make

clear to others the license terms of this work.

The information in this book is distributed on an “as is” basis, without warranty. Although every precaution

has been taken in the preparation of this work, neither the author(s) nor SensioLabs shall have any liability to

any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by

the information contained in this work.

If you find typos or errors, feel free to report them by creating a ticket on the Symfony ticketing system

(http://github.com/symfony/symfony-docs/issues). Based on tickets and users

this book is

continuously updated.

feedback,

Contents at a Glance

The Big Picture ...................................................................................................................................4

The View ............................................................................................................................................9

The Controller ..................................................................................................................................14

The Architecture ...............................................................................................................................21

PDF brought to you by

generated on February 8, 2016

Contents at a Glance | iii

Chapter 1

The Big Picture

Start using Symfony in 10 minutes! This chapter will walk you through the most important concepts

behind Symfony and explain how you can get started quickly by showing you a simple project in action.

If you've used a web framework before, you should feel right at home with Symfony. If not, welcome to

a whole new way of developing web applications.

Installing Symfony

Before continuing reading this chapter, make sure to have installed both PHP and Symfony as explained

in the installation chapter of the Symfony book.

Understanding the Fundamentals

One of the main goals of a framework is to keep your code organized and to allow your application to

evolve easily over time by avoiding the mixing of database calls, HTML tags and other PHP code in the

same script. To achieve this goal with Symfony, you'll first need to learn a few fundamental concepts.

When developing a Symfony application, your responsibility as a developer is to write the code that maps

the user's request (e.g. http://localhost:8000/) to the resource associated with it (the Homepage HTML

page).

The code to execute is defined in actions and controllers. The mapping between user's requests and

that code is defined via the routing configuration. And the contents displayed in the browser are usually

rendered using templates.

When you browsed http://localhost:8000/app/example earlier, Symfony executed the controller

defined in the src/AppBundle/Controller/DefaultController.php file and rendered the app/

Resources/views/default/index.html.twig template. In the following sections you'll learn in detail

the inner workings of Symfony controllers, routes and templates.

PDF brought to you by

generated on February 8, 2016

Chapter 1: The Big Picture | 4

Actions and Controllers

Open the src/AppBundle/Controller/DefaultController.php file and you'll see the following code

(for now, don't look at the @Route configuration because that will be explained in the next section):

Listing 1-1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller

{

/**

  • @Route("/", name="homepage")

*/

public function indexAction()

{

return $this->render('default/index.html.twig');

}

}

In Symfony applications, controllers are usually PHP classes whose names are suffixed with the

Controller word. In this example, the controller is called Default and the PHP class is called

DefaultController.

The methods defined in a controller are called actions, they are usually associated with one URL of the

application and their names are suffixed with Action. In this example, the Default controller has only

one action called index and defined in the indexAction method.

Actions are usually very short - around 10-15 lines of code - because they just call other parts of the

application to get or generate the needed information and then they render a template to show the results

to the user.

In this example, the index action is practically empty because it doesn't need to call any other method.

The action just renders a template with the Homepage. content.

Routing

Symfony routes each request to the action that handles it by matching the requested URL against

the paths

src/AppBundle/Controller/

DefaultController.php file and take a look at the three lines of code above the indexAction method:

application. Open again the

configured by

the

Listing 1-2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// src/AppBundle/Controller/DefaultController.php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller

{

/**

  • @Route("/", name="homepage")

*/

public function indexAction()

{

return $this->render('default/index.html.twig');

}

}

PDF brought to you by

generated on February 8, 2016

Chapter 1: The Big Picture | 5

These three lines define the routing configuration via the @Route() annotation. A PHP annotation is a

convenient way to configure a method without having to write regular PHP code. Beware that annotation

blocks start with /*, whereas regular PHP comments start with /.

The first value of @Route() defines the URL that will trigger the execution of the action. As you don't

have to add the host of your application to the URL (e.g. `http://example.com), these URLs are always

relative and they are usually called paths. In this case, the / path refers to the application homepage. The

second value of @Route() (e.g. name="homepage") is optional and sets the name of this route. For now

this name is not needed, but later it'll be useful for linking pages.

Considering all this, the @Route("/",

name="homepage") annotation creates a new route called

homepage which makes Symfony execute the index action of the Default controller when the user

browses the / path of the application.

In addition to PHP annotations, routes can be configured in YAML, XML or PHP files, as

explained in the Routing chapter of the Symfony book. This flexibility is one of the main features of

Symfony, a framework that never imposes a particular configuration format on you.

Templates

The only content of the index action is this PHP instruction:

Listing 1-3

1 return $this->render('default/index.html.twig');

The $this->render() method is a convenient shortcut to render a template. Symfony provides some

useful shortcuts to any controller extending from the Controller class.

By default, application templates are stored in the app/Resources/views/ directory. Therefore, the

the

app/Resources/views/default/

default/index.html.twig

index.html.twig. Open that file and you'll see the following code:

corresponds

template

to

Listing 1-4

1

2

3

4

5

6

7

8

{# app/Resources/views/default/index.html.twig #}

{% extends 'base.html.twig' %}

{% block body %}

<h1>Welcome to Symfony</h1>

{# ... #}

{% endblock %}

This template is created with Twig1, a template engine created for modern PHP applications. The second

part of this tutorial explains how templates work in Symfony.

Working with Environments

Now that you have a better understanding of how Symfony works, take a closer look at the bottom of any

Symfony rendered page. You should notice a small bar with the Symfony logo. This is the "web debug

toolbar" and it is a Symfony developer's best friend!

Advertisement

1. http://twig.sensiolabs.org/

PDF brought to you by

generated on February 8, 2016

Chapter 1: The Big Picture | 6

But what you see initially is only the tip of the iceberg; click on any of the bar sections to open the profiler

and get much more detailed information about the request, the query parameters, security details and

database queries:

This tool provides so much internal information about your application that you may be worried about

your visitors accessing sensible information. Symfony is aware of this issue and for that reason, it won't

display this bar when your application is running in the production server.

How does Symfony know whether your application is running locally or on a production server? Keep

reading to discover the concept of execution environments.

What is an Environment?

An Environment represents a group of configurations that's used to run your application. Symfony

defines two environments by default: dev (suited for when developing the application locally) and prod

(optimized for when executing the application on production).

When you visit the http://localhost:8000 URL in your browser, you're executing your Symfony

application in the dev environment. To visit your application in the prod environment, visit the

http://localhost:8000/app.php URL instead. If you prefer to always show the dev environment in the

URL, you can visit http://localhost:8000/app_dev.php URL.

PDF brought to you by

generated on February 8, 2016

Chapter 1: The Big Picture | 7

The main difference between environments is that dev is optimized to provide lots of information to the

developer, which means worse application performance. Meanwhile, prod is optimized to get the best

performance, which means that debug information is disabled, as well as the web debug toolbar.

The other difference between environments is the configuration options used to execute the application.

When you access the dev environment, Symfony loads the app/config/config_dev.yml configuration

file. When you access the prod environment, Symfony loads app/config/config_prod.yml file.

Typically, the environments share a large amount of configuration options. For that reason, you put your

common configuration in config.yml and override the specific configuration file for each environment

where necessary:

Listing 1-5

1

2

3

4

5

6

7

app/config/config_dev.yml

imports:

  • { resource: config.yml }

web_profiler:

toolbar: true

intercept_redirects: false

In this example, the config_dev.yml configuration file imports the common config.yml file and then

overrides any existing web debug toolbar configuration with its own options.

For more details on environments, see "Environments & Front Controllers" article.

Final Thoughts

Congratulations! You've had your first taste of Symfony code. That wasn't so hard, was it? There's a lot

more to explore, but you should already see how Symfony makes it really easy to implement web sites

better and faster. If you are eager to learn more about Symfony, dive into the next section: "The View".

PDF brought to you by

generated on February 8, 2016

Chapter 1: The Big Picture | 8

Chapter 2

The View

After reading the first part of this tutorial, you have decided that Symfony was worth another 10 minutes.

In this second part, you will learn more about Twig1, the fast, flexible and secure template engine for PHP

applications. Twig makes your templates more readable and concise; it also makes them more friendly

for web designers.

Getting Familiar with Twig

The official Twig documentation2 is the best resource to learn everything about this template engine. This

section just gives you a quick overview of its main concepts.

A Twig template is a text file that can generate any type of content (HTML, CSS, JavaScript, XML,

CSV, LaTeX, etc.) Twig elements are separated from the rest of the template contents using any of these

delimiters:

{{ ... }}

{{ ... }}

Prints the content of a variable or the result of evaluating an expression;

{% ... %}

{% ... %}

Controls the logic of the template; it is used for example to execute for loops and if statements.

{# ... #}

{# ... #}

Allows including comments inside templates. Contrary to HTML comments, they aren't included

in the rendered template.

Below is a minimal template that illustrates a few basics, using two variables page_title and

navigation, which would be passed into the template:

Listing 2-1

1

2

3

4

<!DOCTYPE html>

<html>

<head>

<title>{{ page_title }}</title>

1. http://twig.sensiolabs.org/

2. http://twig.sensiolabs.org/documentation

PDF brought to you by

generated on February 8, 2016

Chapter 2: The View | 9

5

6

7

8

9

10

11

12

13

14

15

</head>

<body>

<h1>{{ page_title }}</h1>

<ul id="navigation">

{% for item in navigation %}

<li><a href="{{ item.url }}">{{ item.label }}</a></li>

{% endfor %}

</ul>

</body>

</html>

To render a template in Symfony, use the render method from within a controller. If the template needs

variables to generate its contents, pass them as an array using the second optional argument:

Listing 2-2

1

2

3

$this->render('default/index.html.twig', array(

'variable_name' => 'variable_value',

));

Variables passed to a template can be strings, arrays or even objects. Twig abstracts the difference

between them and lets you access "attributes" of a variable with the dot (.) notation. The following code

listing shows how to display the content of a variable passed by the controller depending on its type:

Listing 2-3

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

{# 1. Simple variables #}

{# $this->render('template.html.twig', array(

'name' => 'Fabien')

) #}

{{ name }}

{# 2. Arrays #}

{# $this->render('template.html.twig', array(

'user' => array('name' => 'Fabien'))

) #}

{{ user.name }}

{# alternative syntax for arrays #}

{{ user['name'] }}

{# 3. Objects #}

{# $this->render('template.html.twig', array(

'user' => new User('Fabien'))

) #}

{{ user.name }}

{{ user.getName }}

{# alternative syntax for objects #}

{{ user.name() }}

{{ user.getName() }}

Decorating Templates

More often than not, templates in a project share common elements, like the well-known header and

footer. Twig solves this problem elegantly with a concept called "template inheritance". This feature

allows you to build a base template that contains all the common elements of your site and defines

"blocks" of contents that child templates can override.

PDF brought to you by

generated on February 8, 2016

Chapter 2: The View | 10

The index.html.twig template uses the extends tag to indicate that

base.html.twig template:

it

inherits from the

Listing 2-4

1

2

3

4

5

6

{# app/Resources/views/default/index.html.twig #}

Advertisement

{% extends 'base.html.twig' %}

{% block body %}

<h1>Welcome to Symfony!</h1>

{% endblock %}

Open the app/Resources/views/base.html.twig file that corresponds to the base.html.twig

template and you'll find the following Twig code:

Listing 2-5

1

2

3

4

5

6

7

8

9

10

11

12

13

14

{# app/Resources/views/base.html.twig #}

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<title>{% block title %}Welcome!{% endblock %}</title>

{% block stylesheets %}{% endblock %}

<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />

</head>

<body>

{% block body %}{% endblock %}

{% block javascripts %}{% endblock %}

</body>

</html>

The {% block %} tags tell the template engine that a child template may override those portions of the

template. In this example, the index.html.twig template overrides the body block, but not the title

block, which will display the default content defined in the base.html.twig template.

Using Tags, Filters and Functions

One of the best features of Twig is its extensibility via tags, filters and functions. Take a look at the

following sample template that uses filters extensively to modify the information before displaying it to

the user:

Listing 2-6

1

2

3

4

5

6

7

<h1>{{ article.title|capitalize }}</h1>

<p>{{ article.content|striptags|slice(0, 255) }} ...</p>

<p>Tags: {{ article.tags|sort|join(", ") }}</p>

<p>Activate your account before {{ 'next Monday'|date('M j, Y') }}</p>

Don't forget to check out the official Twig documentation3 to learn everything about filters, functions and

tags.

Including other Templates

The best way to share a snippet of code between several templates is to create a new template fragment

that can then be included from other templates.

3. http://twig.sensiolabs.org/documentation

PDF brought to you by

generated on February 8, 2016

Chapter 2: The View | 11

Imagine that we want to display ads on some pages of our application. First, create a banner.html.twig

template:

Listing 2-7

1

2

3

4

{# app/Resources/views/ads/banner.html.twig #}

<div id="ad-banner">

...

</div>

To display this ad on any page, include the banner.html.twig template using the include() function:

Listing 2-8

1

2

3

4

5

6

7

8

{# app/Resources/views/default/index.html.twig #}

{% extends 'base.html.twig' %}

{% block body %}

<h1>Welcome to Symfony!</h1>

{{ include('ads/banner.html.twig') }}

{% endblock %}

Embedding other Controllers

And what if you want to embed the result of another controller in a template? That's very useful when

working with Ajax, or when the embedded template needs some variable not available in the main

template.

Suppose you've created a topArticlesAction controller method to display the most popular articles of

your website. If you want to "render" the result of that method (usually some HTML content) inside the

index template, use the render() function:

Listing 2-9

1

2

{# app/Resources/views/index.html.twig #}

{{ render(controller('AppBundle:Default:topArticles')) }}

Here, the render() and controller() functions use the special AppBundle:Default:topArticles

syntax to refer to the topArticlesAction action of the Default controller (the AppBundle part will be

explained later):

Listing 2-10

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// src/AppBundle/Controller/DefaultController.php

class DefaultController extends Controller

{

public function topArticlesAction()

{

// look for the most popular articles in the database

$articles = ...;

return $this->render('default/top_articles.html.twig', array(

'articles' => $articles,

));

}

// ...

}

PDF brought to you by

generated on February 8, 2016

Chapter 2: The View | 12

Creating Links between Pages

Creating links between pages is a must for web applications. Instead of hardcoding URLs in templates,

the path function knows how to generate URLs based on the routing configuration. That way, all your

URLs can be easily updated by just changing the configuration:

Listing 2-11

1 <a href="{{ path('homepage') }}">Return to homepage</a>

The path function takes the route name as the first argument and you can optionally pass an array of

route parameters as the second argument.

The url function is very similar to the path function, but generates absolute URLs, which is very

handy when rendering emails and RSS files: <a href="{{ url('homepage') }}">Visit our

website</a>.

Including Assets: Images, JavaScripts and Stylesheets

What would the Internet be without images, JavaScripts and stylesheets? Symfony provides the asset

function to deal with them easily:

Listing 2-12

1

2

3

<link href="{{ asset('css/blog.css') }}" rel="stylesheet" type="text/css" />

<img src="{{ asset('images/logo.png') }}" />

The asset() function looks for the web assets inside the web/ directory. If you store them in another

directory, read this article to learn how to manage web assets.

Using the asset function, your application is more portable. The reason is that you can move the

application root directory anywhere under your web root directory without changing anything in your

template's code.

Final Thoughts

Twig is simple yet powerful. Thanks to layouts, blocks, templates and action inclusions, it is very easy to

organize your templates in a logical and extensible way.

You have only been working with Symfony for about 20 minutes, but you can already do pretty amazing

stuff with it. That's the power of Symfony. Learning the basics is easy and you will soon learn that this

simplicity is hidden under a very flexible architecture.

But I'm getting ahead of myself. First, you need to learn more about the controller and that's exactly the

topic of the next part of this tutorial. Ready for another 10 minutes with Symfony?

PDF brought to you by

generated on February 8, 2016

Chapter 2: The View | 13

Chapter 3

The Controller

Still here after the first two parts? You are already becoming a Symfony fan! Without further ado, discover

what controllers can do for you.

Returning Raw Responses

Symfony defines itself as a Request-Response framework. When the user makes a request to your

application, Symfony creates a Request object to encapsulate all the information related to that request.

Similarly, the result of executing any action of any controller is the creation of a Response object which

Symfony uses to generate the HTML content returned to the user.

So far, all the actions shown in this tutorial used the $this->render() shortcut to return a rendered

response as result. In case you need it, you can also create a raw Response object to return any text

content:

Listing 3-1

1

2

3

4

5

6

7

Advertisement

8

9

10

11

12

13

14

15

16

17

// src/AppBundle/Controller/DefaultController.php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller

{

/**

  • @Route("/", name="homepage")

*/

public function indexAction()

{

return new Response('Welcome to Symfony!');

}

}

PDF brought to you by

generated on February 8, 2016

Chapter 3: The Controller | 14

Route Parameters

Most of the time, the URLs of applications include variable parts on them. If you are creating for

example a blog application, the URL to display the articles should include their title or some other unique

identifier to let the application know the exact article to display.

In Symfony applications, the variable parts of the routes are enclosed in curly braces (e.g. /blog/read/

{article_title}/). Each variable part is assigned a unique name that can be used later in the controller

to retrieve each value.

Let's create a new action with route variables to show this feature in action. Open the src/AppBundle/

Controller/DefaultController.php file and add a new method called helloAction with the following

content:

Listing 3-2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// src/AppBundle/Controller/DefaultController.php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller

{

// ...

/**

  • @Route("/hello/{name}", name="hello")

*/

public function helloAction($name)

{

return $this->render('default/hello.html.twig', array(

'name' => $name

));

}

}

Open your browser and access the http://localhost:8000/hello/fabien URL to see the result of

executing this new action. Instead of the action result, you'll see an error page. As you probably guessed,

the cause of this error is that we're trying to render a template (default/hello.html.twig) that doesn't

exist yet.

Create the new app/Resources/views/default/hello.html.twig template with the following content:

Listing 3-3

1

2

3

4

5

6

{# app/Resources/views/default/hello.html.twig #}

{% extends 'base.html.twig' %}

{% block body %}

<h1>Hi {{ name }}! Welcome to Symfony!</h1>

{% endblock %}

Browse again the http://localhost:8000/hello/fabien URL and you'll see this new template

rendered with the information passed by the controller. If you change the last part of the URL (e.g.

http://localhost:8000/hello/thomas) and reload your browser, the page will display a different

message. And if you remove the last part of the URL (e.g. http://localhost:8000/hello), Symfony will

display an error because the route expects a name and you haven't provided it.

PDF brought to you by

generated on February 8, 2016

Chapter 3: The Controller | 15

Using Formats

Nowadays, a web application should be able to deliver more than just HTML pages. From XML for RSS

feeds or Web Services, to JSON for Ajax requests, there are plenty of different formats to choose from.

Supporting those formats in Symfony is straightforward thanks to a special variable called _format which

stores the format requested by the user.

Tweak the hello route by adding a new _format variable with html as its default value:

Listing 3-4

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// src/AppBundle/Controller/DefaultController.php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

// ...

/**

  • @Route("/hello/{name}.{_format}", defaults={"_format"="html"}, name="hello")

*/

public function helloAction($name, $_format)

{

return $this->render('default/hello.'.$_format.'.twig', array(

'name' => $name

));

}

Obviously, when you support several request formats, you have to provide a template for each of the

supported formats. In this case, you should create a new hello.xml.twig template:

Listing 3-5

1

2

3

4

<!-- app/Resources/views/default/hello.xml.twig -->

<hello>

<name>{{ name }}</name>

</hello>

Now, when you browse to http://localhost:8000/hello/fabien, you'll see the regular HTML page

because html is the default format. When visiting http://localhost:8000/hello/fabien.html you'll

get again the HTML page, this time because you explicitly asked for the html format. Lastly, if you

visit http://localhost:8000/hello/fabien.xml you'll see the new XML template rendered in your

browser.

That's all there is to it. For standard formats, Symfony will also automatically choose the best Content-

Type header for the response. To restrict the formats supported by a given action, use the requirements

option of the @Route() annotation:

Listing 3-6

1

2

3

4

5

6

7

8

9

10

11

12

13

14

// src/AppBundle/Controller/DefaultController.php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

// ...

/**

  • @Route("/hello/{name}.{_format}",
  • defaults = {"_format"="html"},
  • requirements = { "_format" = "html|xml|json" },
  • name = "hello"
  • )

*/

public function helloAction($name, $_format)

PDF brought to you by

generated on February 8, 2016

Chapter 3: The Controller | 16

15

16

17

18

19

{

}

return $this->render('default/hello.'.$_format.'.twig', array(

'name' => $name

));

The hello action will now match URLs like /hello/fabien.xml or /hello/fabien.json, but it will

show a 404 error if you try to get URLs like /hello/fabien.js, because the value of the _format variable

doesn't meet its requirements.

Advertisement

Redirecting

If you want to redirect the user to another page, use the redirectToRoute() method:

Listing 3-7

1

2

3

4

5

6

7

8

9

10

11

// src/AppBundle/Controller/DefaultController.php

class DefaultController extends Controller

{

/**

  • @Route("/", name="homepage")

*/

public function indexAction()

{

return $this->redirectToRoute('hello', array('name' => 'Fabien'));

}

}

The redirectToRoute() method takes as arguments the route name and an optional array of parameters

and redirects the user to the URL generated with those arguments.

Displaying Error Pages

Errors will inevitably happen during the execution of every web application. In the case of 404 errors,

Symfony includes a handy shortcut that you can use in your controllers:

Listing 3-8

1

2

3

4

5

6

7

8

9

10

11

12

13

14

// src/AppBundle/Controller/DefaultController.php

// ...

class DefaultController extends Controller

{

/**

  • @Route("/", name="homepage")

*/

public function indexAction()

{

// ...

throw $this->createNotFoundException();

}

}

For 500 errors, just throw a regular PHP exception inside the controller and Symfony will transform it

into a proper 500 error page:

Listing 3-9

PDF brought to you by

generated on February 8, 2016

Chapter 3: The Controller | 17

1

2

3

4

5

6

7

8

9

10

11

12

13

14

// src/AppBundle/Controller/DefaultController.php

// ...

class DefaultController extends Controller

{

/**

  • @Route("/", name="homepage")

*/

public function indexAction()

{

// ...

throw new \Exception('Something went horribly wrong!');

}

}

Getting Information from the Request

Sometimes your controllers need to access the information related to the user request, such as their

preferred language, IP address or the URL query parameters. To get access to this information, add a new

argument of type Request to the action. The name of this new argument doesn't matter, but it must be

preceded by the Request type in order to work (don't forget to add the new use statement that imports

this Request class):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

// src/AppBundle/Controller/DefaultController.php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Symfony\Component\HttpFoundation\Request;

class DefaultController extends Controller

{

/**

  • @Route("/", name="homepage")

*/

public function indexAction(Request $request)

{

// is it an Ajax request?

$isAjax = $request->isXmlHttpRequest();

// what's the preferred language of the user?

$language = $request->getPreferredLanguage(array('en', 'fr'));

// get the value of a $_GET parameter

$pageName = $request->query->get('page');

// get the value of a $_POST parameter

$pageName = $request->request->get('page');

}

}

In a template, you can also access the Request object via the special app.request variable automatically

provided by Symfony:

PDF brought to you by

generated on February 8, 2016

Chapter 3: The Controller | 18

Listing 3-10

Listing 3-11

1

2

3

{{ app.request.query.get('page') }}

{{ app.request.request.get('page') }}

Persisting Data in the Session

Even if the HTTP protocol is stateless, Symfony provides a nice session object that represents the client

(be it a real person using a browser, a bot, or a web service). Between two requests, Symfony stores the

attributes in a cookie by using native PHP sessions.

Storing and retrieving information from the session can be easily achieved from any controller:

Listing 3-12

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

use Symfony\Component\HttpFoundation\Request;

public function indexAction(Request $request)

{

$session = $request->getSession();

// store an attribute for reuse during a later user request

$session->set('foo', 'bar');

// get the value of a session attribute

$foo = $session->get('foo');

// use a default value if the attribute doesn't exist

$foo = $session->get('foo', 'default_value');

}

You can also store "flash messages" that will auto-delete after the next request. They are useful when

you need to set a success message b...