We want to show a flash message as the result of executing some controller. This message will only last for the next request.
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(...);
}
}
- 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()
Your controller code is coupled with the base controller provided with Symfony. It won't work outside a Symfony application.
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 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(...);
}
}
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.
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!
Well, coupling is something to have always in mind, in my opinion, even when we are talking about controllers.
I see some problems with the
$this->addFlash()
solution:So what's the point of adding the new method? Saving a few seconds every time you write an addFlash()? Is it worth it? Really?
If you don't like
$this->get('session')->getFlashBag()->add($severity, $message)
you can create your own helper (or the framework could give you one) so that you could do something like:Which is a bit longer than
But hasn't any of the problems exposed before.