Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save devdrops/05e1c921b2fb3b26428d21e7cc2aa0b0 to your computer and use it in GitHub Desktop.
Save devdrops/05e1c921b2fb3b26428d21e7cc2aa0b0 to your computer and use it in GitHub Desktop.
Discussion about the different solutions to display a flash message

The problem to solve

We want to show a flash message as the result of executing some controller. This message will only last for the next request.

Proposed Solution #1

I propose to use the new addFlash() method available in the base controller of Symfony 2.6:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{
    public function myAction()
    {
        // ... 3 or 4 lines of code

        $this->addFlash('success', 'The product was successfully inserted.');

        return $this->render(...);
    }
}

Requirements of the solution

  • 0 new custom classes
  • 0 new custom methods or functions (addFlash() is provided by the framework)
  • 0 new custom listeners, services or parameters

Total time required by the solution is about 3 seconds, the time needed to type $this->addFlash()

Drawbacks of the solution

Your controller code is coupled with the base controller provided with Symfony. It won't work outside a Symfony application.

Final comments

I don't mind about the coupling in this case because:

  • Controllers are a thin layer of glue-code provided by the framework. Coupling to it allows me to be more productive.
  • I advocate for agressively decoupling your business logic from the underlying framework. But at the same time, I recommend to agressively couple your controllers to the framework, to take advantage of its features. Otherwise, what is the point of using a framework?
  • Spending a lot of time decupling your controllers from the framework is not worth it. In case you change your framework, it's 100% sure that you'll have to make lots of changes in your code. Updating 4 or 5 lines of controller code will be fast and easy.

Proposed Solution #2

Proposed by Carles Climent in this comment

class MyController
{
    public function myAction()
    {
        // ... 3 or 4 lines of code

        $this->get('flash_handler')->add('success', 'The product was successfully inserted.');

        return $this->container->get('templating')->renderResponse(...);
    }
}

Requirements of the solution

First, you have to define these two classes:

interface FlashHandler
{
    public function add($severity, $message);
}
class SymfonyFlashHandler implements FlashHandler
{
    private $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function add($severity, $message)
    {
        $this->session->getFlashBag()->add($severity, $message);

        return $this;
    }
}

Then, you have to define a new service for the flash handler:

parameters:
    flash_handler.class: [...]\FlashHandler

services:
    flash_handler:
        class:           "%flash_handler.class%"
        arguments:       [@session]

The main advantage of this solution is that Controller is no longer coupled with Symfony. It will work outside a Symfony application.

Other Proposed Solutions

Please propose other solutions to this problem and don't forget to provide the full code needed by your solution. This way we'll be able to compare them all. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment