ZetCode

Symfony Flash messages

last modified July 5, 2020

Symfony Flash messages tutorial shows how to create flash messages in Symfony. Flash messages are temporary messages used for user notifications. They are stored in a session and vanish as soon as they are retrieved.

Symfony

Symfony is a set of reusable PHP components and a PHP framework for web projects. Symfony was published as free software in 2005. Symfony was heavily inspired by the Spring Framework.

Symfony Flash example

In the following example, we have a simple form with one input box for a user name. If the user enters an invalid name (empty or containing only spaces), the application shows a flash notification above the form.

Note: In our application, we have a GET form. A GET method is considered safe, so we do not implement a CSRF protection. The Symfony CSRF tutorial covers CSRF protection in Symfony.

$ symfony new symflash

With symfony CLI we create a new Symfony skeleton project.

$ cd symflash

We go to the project directory.

$ php bin/console --version
Symfony 5.0.8 (env: dev, debug: true)

We use Symfony 5.0.8.

$ composer require annotations twig

We install two packages: annotations and twig.

$ composer require maker --dev

We install the Symfony maker.

src/Service/Validate.php
<?php

namespace App\Service;

class Validate
{
    public function isValid(?string $name): bool
    {
        if (!isset($name) || trim($name) === '') {

            return false;
        } else {

            return true;
        }
    }
}

The Validate service checks if the provided string is empty or contains only spaces.

Note: In production applications, we use some validation library such as Symfony's symfony/validator or PHP Rackit or Respect.

$ php bin/console make:controller FormController

A FormController is created.

src/Controller/FormController.php
<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Service\Validate;

class FormController extends AbstractController
{
    /**
     * @Route("/", name="index")
     */
    public function index(): Response
    {
        return $this->render('form/index.html.twig');
    }

    /**
     * @Route("/form", name="do-form")
     * @param Request $request
     * @param Validate $valService
     * @return RedirectResponse|Response
     */
    public function doForm(Request $request, Validate $valService): Response
    {
        $name = $request->query->get("name");

        $validated = $valService->isValid($name);

        if ($validated) {

            $msg = sprintf("Hello %s!", $name);

            return new Response($msg,  Response::HTTP_OK,
                ['content-type' => 'text/plain']);
        } else {

            $this->addFlash(
                'notice', 'Invalid name entered'
            );

            return $this->redirectToRoute("index");
        }
    }
}

The FormController responds to root and form paths.

/**
 * @Route("/", name="index")
 */
public function index()
{
    return $this->render('form/index.html.twig');
}

The root path returns an HTML form.

/**
 * @Route("/form", name="do-form")
 * @param Request $request
 * @param Validate $valService
 * @return RedirectResponse|Response
 */
public function doForm(Request $request, Validate $valService): Response
{

In the doForm() method, we inject a Request object and a Validate service.

$name = $request->get("name");
$validated = $valService->isValid($name);

We retrieve the name input and validate it.

if ($validated) {

    $msg = sprintf("Hello %s!", $name);

    return new Response($msg,  Response::HTTP_OK,
        ['content-type' => 'text/plain']);
}

If the validation was successfull, we send a plain text response to the client.

$this->addFlash(
    'notice', 'Invalid name entered'
);

return $this->redirectToRoute("index");

If the input is not valid, we add a flash message with addFlash() and redirect to the index route.

templates/form/index.html.twig
{% extends 'base.html.twig' %}

{% block title %}Home page{% endblock %}

{% block stylesheets %}
    <style> .flash-notice { color: red } </style>
{% endblock %}

{% block body %}

    {% for message in app.flashes('notice') %}
        <div class="flash-notice">
            {{ message }}
        </div>
    {% endfor %}

    <form action="{{ path('do-form') }}">

        <div>
            <label for="name">Enter your name:</label>1
            <input type="text" name="name" id="name">
        </div>

        <button type="submit">Send</button>

    </form>

{% endblock %}

The FormController returns a form page. It contains an input for user name.

{% for message in app.flashes('notice') %}
    <div class="flash-notice">
        {{ message }}
    </div>
{% endfor %}

When the application redirects to this page, we go through flash messages and display them in div tags above the form.

templates/base.html.twig
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        {% block stylesheets %}{% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
    </body>
</html>

The base.html.twig template contains code that is shared by other template files. It defines blocks that will be replaced in children templates.

$ symfony serve

We run the application and locate to localhost:8000.

In this tutorial we have worked with flash messages in Symfony.

List all Symfony tutorials.