Palestinian Flag Solidarity with Palestine. We seek justice and peace, and strongly oppose all forms of injustice and genocide.
Enjoying PHPFlasher? Show your support with a star on GitHub! Thank you

Requirements

PHPFlasher helps you easily add flash notifications to your Symfony projects, improving user feedback with minimal setup.

Required

PHP Version

v8.2 or higher
Required

Symfony Version

v7.0 or higher

Using older PHP or Symfony versions?

If you need to use PHP < v8.2 or Symfony < v7.0, use PHPFlasher v1 instead. It supports PHP ≥ v5.3 and Symfony ≥ v2.0. Check out the v1 documentation here .

Installation

PHPFlasher is modular. You can install only the parts you need.

Run this command to install it:

Terminal
Installation
composer require php-flasher/flasher-symfony

After installing, run this command to set up the required assets:

Terminal
Setup Assets
php bin/console flasher:install

Ready in under a minute!

That's it! No need for complex configuration - PHPFlasher works right out of the box with sensible defaults.

Best Practice

Commit the installed assets to your version control system to ensure everyone on your team has the same notification experience.

Usage

Basic Usage

Here's a basic example of using PHPFlasher in a Symfony controller:

ProductController.php
<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class ProductController extends AbstractController
{
    #[Route('/product/create', name: 'app_product_create')]
    public function create(): Response
    {
        // Your logic to create a product

        // Add a success notification
        flash()->success('Product created successfully!');

        return $this->redirectToRoute('app_product_list');
    }
}

Pro Tip: Two Ways to Use PHPFlasher

PHPFlasher provides two ways to create notifications:

  • Helper function: flash()->success('Message');
  • Dependency injection: private FlasherInterface $flasher

Notification Types

PHPFlasher supports different types of notifications:

NotificationTypes.php
// Success message
flash()->success('Your changes have been saved!');

// Error message
flash()->error('Something went wrong!');

// Warning message
flash()->warning('Please review your data before proceeding.');

// Info message
flash()->info('The system will be down for maintenance tonight.');
Success

Your changes have been saved!

Error

Something went wrong!

Warning

Please review your data before proceeding.

Info

The system will be down for maintenance tonight.

Adding a Title

You can add a title to your notifications:

Title.php
flash()->success('Your profile has been updated successfully.', 'Profile Updated');

Profile Updated

Your profile has been updated successfully.

Notification Options

Customize your notifications with various options:

Options.php
flash()
    ->option('position', 'top-center')  // Position on the screen
    ->option('timeout', 5000)           // How long to display (milliseconds)
    ->option('rtl', true)               // Right-to-left support
    ->success('Your changes have been saved!');

Positioning

top-right top-left top-center bottom-right bottom-left bottom-center

Timing

Control how long notifications display with the timeout option (milliseconds).

Set to 0 to require manual dismissal.

Animations

Choose from various animations:

fade slide zoom flip

Common Examples

Here are some common examples of using PHPFlasher in your Symfony applications.

CRUD Operations

A complete example showing notifications for Create, Read, Update, and Delete operations:

ArticleController.php
<?php

namespace App\Controller;

use App\Entity\Article;
use App\Form\ArticleType;
use App\Repository\ArticleRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class ArticleController extends AbstractController
{
    #[Route('/article/new', name: 'app_article_new', methods: ['GET', 'POST'])]
    public function new(Request $request, ArticleRepository $articleRepository): Response
    {
        $article = new Article();
        $form = $this->createForm(ArticleType::class, $article);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $articleRepository->save($article, true);
            flash()->success('Article created successfully!');

            return $this->redirectToRoute('app_article_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->render('article/new.html.twig', [
            'article' => $article,
            'form' => $form,
        ]);
    }

    #[Route('/article/{id}/edit', name: 'app_article_edit', methods: ['GET', 'POST'])]
    public function edit(Request $request, Article $article, ArticleRepository $articleRepository): Response
    {
        $form = $this->createForm(ArticleType::class, $article);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $articleRepository->save($article, true);
            flash()->success('Article updated successfully!');

            return $this->redirectToRoute('app_article_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->render('article/edit.html.twig', [
            'article' => $article,
            'form' => $form,
        ]);
    }

    #[Route('/article/{id}', name: 'app_article_delete', methods: ['POST'])]
    public function delete(Request $request, Article $article, ArticleRepository $articleRepository): Response
    {
        if ($this->isCsrfTokenValid('delete'.$article->getId(), $request->request->get('_token'))) {
            $articleRepository->remove($article, true);
            flash()->success('Article deleted successfully!');
        } else {
            flash()->error('Invalid token. Please try again.');
        }

        return $this->redirectToRoute('app_article_index', [], Response::HTTP_SEE_OTHER);
    }
}

Form Validation

Display validation errors to users:

RegistrationController.php
<?php

namespace App\Controller;

use App\Entity\User;
use App\Form\RegistrationType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class RegistrationController extends AbstractController
{
    #[Route('/register', name: 'app_register')]
    public function register(Request $request): Response
    {
        $user = new User();
        $form = $this->createForm(RegistrationType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // Save user logic here
            flash()->success('Registration successful! Please log in.');

            return $this->redirectToRoute('app_login');
        }

        if ($form->isSubmitted() && !$form->isValid()) {
            flash()->error('Please correct the errors in the form.');
        }

        return $this->render('registration/register.html.twig', [
            'form' => $form,
        ]);
    }
}

AJAX Requests

Using PHPFlasher with AJAX requests:

APIController.php
<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class ApiController extends AbstractController
{
    #[Route('/api/update', name: 'api_update', methods: ['POST'])]
    public function update(Request $request): JsonResponse
    {
        // Process the request
        $data = json_decode($request->getContent(), true);

        // Your business logic here

        // Flash messages will be rendered in the response
        flash()->success('Data updated successfully!');

        return $this->json(['status' => 'success']);
    }
}

Configuration

PHPFlasher can be configured to customize its behavior. The configuration file is located at config/packages/flasher.yaml.

flasher.yaml
Configuration
# config/packages/flasher.yaml

flasher:
    main:
        filter:
            # Filter flash messages by priority or criteria
            priority: ~

        # Limit the number of flash messages displayed
        limit: ~

        # Map Flash messages to specific criteria
        map: []

        # Automatically inject Flasher scripts into your HTML
        inject_assets: true

        # Use bulma CSS framework
        use_bulma: false

        # Use tailwind CSS framework
        use_tailwind: false

        # Use bootstrap CSS framework
        use_bootstrap: false

        # Default flash notification options
        options:
            # Animation: fade, slide, zoom, flip, bounce, etc.
            animation: true

            # Close button on notifications
            close_button: false

            # Display progress bar
            progress_bar: true

            # Notification position: top-right, top-left, bottom-right, bottom-left, top-center, bottom-center
            position: top-right

            # Right-to-left support
            rtl: false

            # Time before notification auto-hides (in milliseconds)
            timeout: 5000

        # Translate flash messages
        translate: true

        # Flash messages translation domain
        translation_domain: flasher

        # Default rendering context
        default_context: ~

        # Available rendering contexts
        contexts: []

Presets

PHPFlasher provides configuration presets for different notification styles.

Available Presets

Default

Balanced notifications with standard animations and positioning.

flasher: default

Minimal

Clean notifications with minimal styling and effects.

flasher: minimal

Translations

PHPFlasher supports translation of flash messages using Symfony's translation component.

Enabling Translations

To enable translations, set the translate option to true in your configuration:

flasher.yaml
# config/packages/flasher.yaml

flasher:
    translate: true
    translation_domain: flasher

Creating Translation Files

Create translation files in the translations/ directory:

translations/flasher.en.yaml
# translations/flasher.en.yaml
success:
    resource_created: '{resource} created successfully.'
    resource_updated: '{resource} updated successfully.'
    resource_deleted: '{resource} deleted successfully.'

error:
    general: 'An error occurred. Please try again.'
    not_found: '{resource} not found.'
    unauthorized: 'You are not authorized to perform this action.'

info:
    welcome: 'Welcome back!'
    maintenance: 'The system will be down for maintenance tonight.'

warning:
    review_data: 'Please review your data before proceeding.'
    unsaved_changes: 'You have unsaved changes. Are you sure you want to leave?'

Using Translated Messages

Use translation keys in your controllers:

ProductController.php
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    public function create(): Response
    {
        // Your logic to create a product

        // Use translation key
        flash('resource_created', ['resource' => 'Product'])->success();

        return $this->redirectToRoute('app_product_list');
    }
}