Skip to content

Flash Messages Lab

Flash Instructions: Implementing Flash Messages

Section titled “Flash Instructions: Implementing Flash Messages”

In this lab, you will implement a flash messaging system for your Slim 4 application. Flash messages provide temporary user feedback after form submissions, login attempts, and other actions. By the end of this lab, you’ll have a fully functional flash messaging system using Bootstrap alerts.


By completing this lab, you will:

  • Understand what flash messages are and when to use them.
  • Create a FlashMessage helper class for managing temporary messages.
  • Integrate flash messages with the BaseController redirect() method.
  • Display flash messages in views using Bootstrap alerts.
  • Implement the Post-Redirect-Get (PRG) pattern correctly.
  • Handle success, error, info, and warning messages.

Before starting this lab, ensure you have:

  • Completed the Session Middleware lab (flash messages require sessions).
  • A working Slim 4 application with SessionMiddleware registered
  • Basic understanding of the BaseController pattern.
  • Bootstrap CSS included in your views (for styled alerts).
  • Your development environment set up and running.

Step 1: Create the FlashMessage Helper Class

Section titled “Step 1: Create the FlashMessage Helper Class”

Objective: Create a helper class that manages flash messages stored in the session.

Instructions:

  1. Navigate to your app/Helpers/ directory
  2. Create a new file named FlashMessage.php
  3. Copy and paste the following code:
app/Helpers/FlashMessage.php
<?php
namespace App\Helpers;
class FlashMessage
{
private const FLASH_KEY = 'flash_messages';
/**
* Add a success message.
*/
public static function success(string $message): void
{
self::add('success', $message);
}
/**
* Add an error message.
*/
public static function error(string $message): void
{
self::add('error', $message);
}
/**
* Add an info message.
*/
public static function info(string $message): void
{
self::add('info', $message);
}
/**
* Add a warning message.
*/
public static function warning(string $message): void
{
self::add('warning', $message);
}
/**
* Add a flash message of any type.
*/
public static function add(string $type, string $message): void
{
if (!isset($_SESSION[self::FLASH_KEY])) {
$_SESSION[self::FLASH_KEY] = [];
}
$_SESSION[self::FLASH_KEY][] = [
'type' => $type,
'message' => $message
];
}
/**
* Get all flash messages and clear them.
*/
public static function get(): array
{
$messages = $_SESSION[self::FLASH_KEY] ?? [];
unset($_SESSION[self::FLASH_KEY]);
return $messages;
}
/**
* Check if there are any flash messages.
*/
public static function has(): bool
{
return !empty($_SESSION[self::FLASH_KEY]);
}
/**
* Clear all flash messages without retrieving them.
*/
public static function clear(): void
{
unset($_SESSION[self::FLASH_KEY]);
}
/**
* Render all flash messages as Bootstrap alerts.
*/
public static function render(bool $dismissible = true): string
{
$messages = self::get();
if (empty($messages)) {
return '';
}
$bootstrapTypes = [
'success' => 'success',
'error' => 'danger',
'info' => 'info',
'warning' => 'warning'
];
$html = '';
foreach ($messages as $flash) {
$type = $bootstrapTypes[$flash['type']] ?? 'info';
$message = htmlspecialchars($flash['message']);
if ($dismissible) {
$html .= <<<HTML
<div class="alert alert-{$type} alert-dismissible fade show" role="alert">
{$message}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
HTML;
} else {
$html .= <<<HTML
<div class="alert alert-{$type}" role="alert">
{$message}
</div>
HTML;
}
}
return $html;
}
}
  1. Save the file

What you just created:

  • A FlashMessage helper class with methods for different message types
  • Methods to add, retrieve, check, and clear flash messages
  • A render() method that automatically generates Bootstrap alert HTML
  • Automatic message cleanup after display
  • XSS protection with htmlspecialchars()

Objective: Create a controller to demonstrate flash message functionality.

Instructions:

  1. Navigate to your app/Controllers/ directory
  2. Create a new file named FlashDemoController.php
  3. Implement a controller class that extends BaseController with the following requirements:

Class Structure:

<?php
namespace App\Controllers;
use App\Helpers\FlashMessage;
use DI\Container;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class FlashDemoController extends BaseController
{
public function __construct(Container $container)
{
parent::__construct($container);
}
// TODO: Implement the methods below
}

Controller callback methods to implement:

Create the following public controller callback methods. Each controller callback method should:

  • Accept the standard Slim framework callback method parameters: Request $request, Response $response, array $args
  • Return a Response object
Callback Method NameWhat It Should Do
index()Render the flash/flashIndexView.php view with a title “Flash Messages Demo”
success()Add a success flash message, then redirect to the flash.demo route
error()Add an error flash message, then redirect to the flash.demo route
info()Add an info flash message, then redirect to the flash.demo route
warning()Add a warning flash message, then redirect to the flash.demo route
multiple()Add 2-3 flash messages of different types, then redirect to the flash.demo route

Implementation Hints:

Click to see hints for implementing the methods

For the index() method:

public function index(Request $request, Response $response, array $args): Response
{
// Use $this->render() to render the view
// Pass 'title' in the data array
}

For message methods (success(), error(), etc.):

public function success(Request $request, Response $response, array $args): Response
{
// 1. Use FlashMessage::success() to add a message
// 2. Use $this->redirect() to redirect to 'flash.demo' route
}

For the multiple() method:

public function multiple(Request $request, Response $response, array $args): Response
{
// 1. Call FlashMessage::success() with a message
// 2. Call FlashMessage::info() with a different message
// 3. Call FlashMessage::warning() with another message
// 4. Use $this->redirect() to redirect to 'flash.demo' route
}

Key Points to Remember:

  • Use FlashMessage::success(), FlashMessage::error(), FlashMessage::info(), or FlashMessage::warning()
  • Always use $this->redirect($request, $response, 'route.name') after setting flash messages
  • The message text can be anything descriptive (e.g., “This is a success message!”)
  • For multiple(), demonstrate that you can set multiple messages before redirecting
  1. Save the file

What you should have created:

  • A controller extending BaseController with a constructor
  • An index() method that renders a view
  • Five methods that set flash messages and redirect
  • Proper use of the Post-Redirect-Get (PRG) pattern

Objective: Add routes for the flash message demo controller.

Instructions:

  1. Open your app/Routes/web-routes.php file
  2. Add the following import at the top:
use App\Controllers\FlashDemoController;
  1. Add these routes:
// Flash message demo routes
$app->get('/flash', [FlashDemoController::class, 'index'])->setName('flash.demo');
$app->post('/flash/success', [FlashDemoController::class, 'success'])->setName('flash.success');
$app->post('/flash/error', [FlashDemoController::class, 'error'])->setName('flash.error');
$app->post('/flash/info', [FlashDemoController::class, 'info'])->setName('flash.info');
$app->post('/flash/warning', [FlashDemoController::class, 'warning'])->setName('flash.warning');
$app->post('/flash/multiple', [FlashDemoController::class, 'multiple'])->setName('flash.multiple');
  1. Save the file

Objective: Create a view that displays flash messages and provides buttons to test each message type.

Instructions:

  1. Navigate to your views/ directory
  2. Create a new folder named flash/
  3. Inside flash/, create a file named flashIndexView.php
  4. Copy and paste the following code:
views/flash/flashIndexView.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($title ?? 'Flash Demo') ?></title>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1 class="mb-4"><?= htmlspecialchars($title ?? 'Flash Demo') ?></h1>
<!-- Flash Messages Display Area -->
<div class="mb-4">
<?= App\Helpers\FlashMessage::render() ?>
</div>
<div class="card">
<div class="card-header">
<h5>Test Flash Messages</h5>
</div>
<div class="card-body">
<p class="card-text">Click the buttons below to test different types of flash messages:</p>
<div class="d-grid gap-2">
<form method="POST" action="flash/success">
<button type="submit" class="btn btn-success w-100">
Show Success Message
</button>
</form>
<form method="POST" action="flash/error">
<button type="submit" class="btn btn-danger w-100">
Show Error Message
</button>
</form>
<form method="POST" action="flash/info">
<button type="submit" class="btn btn-info w-100">
Show Info Message
</button>
</form>
<form method="POST" action="flash/warning">
<button type="submit" class="btn btn-warning w-100">
Show Warning Message
</button>
</form>
<form method="POST" action="flash/multiple">
<button type="submit" class="btn btn-primary w-100">
Show Multiple Messages
</button>
</form>
</div>
</div>
</div>
<div class="alert alert-info mt-4" role="alert">
<strong>Note:</strong> Flash messages appear once and then disappear. Refresh the page to clear any visible messages.
</div>
</div>
<!-- Bootstrap 5 JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
  1. Save the file

What you just created:

  • A view that displays flash messages using FlashMessage::render()
  • Buttons to test each message type
  • Bootstrap-styled layout
  • Forms using POST method to demonstrate PRG pattern

Objective: Verify that flash messages work correctly.

Instructions:

  1. Start your development server (if not already running)
  2. Visit http://localhost/[your-app-name]/flash in your browser
  3. Click each button and observe the flash messages:
    • “Show Success Message” → Green alert
    • “Show Error Message” → Red alert
    • “Show Info Message” → Blue alert
    • “Show Warning Message” → Yellow alert
    • “Show Multiple Messages” → Three different alerts

Expected Behavior:

  • ✅ Messages appear at the top of the page after redirect
  • ✅ Messages have appropriate colors (success=green, error=red, etc.)
  • ✅ Messages have close buttons (dismissible)
  • ✅ Refreshing the page clears all messages
  • ✅ Multiple messages can be displayed at once

If messages don’t appear:

  • Verify SessionMiddleware is registered in config/middleware.php
  • Check browser console for JavaScript errors
  • Ensure Bootstrap CSS and JS are loading
  • Verify the FlashMessage::render() line is in your view

Before submitting your lab, verify the following:

  • FlashMessage.php exists in app/Helpers/ directory
  • FlashDemoController.php exists in app/Controllers/ directory
  • All six controller methods are implemented correctly (index, success, error, info, warning, multiple)
  • Flash demo routes are registered in web-routes.php
  • Flash demo page (/flash) displays all message types correctly
  • Messages disappear after page refresh
  • Multiple messages can be displayed simultaneously
  • Close buttons work on dismissible alerts

MethodDescriptionExample
success($msg)Add a success message (green alert)FlashMessage::success('Saved!')
error($msg)Add an error message (red alert)FlashMessage::error('Invalid input')
info($msg)Add an info message (blue alert)FlashMessage::info('Check your email')
warning($msg)Add a warning message (yellow alert)FlashMessage::warning('Trial ending soon')
add($type, $msg)Add a custom message typeFlashMessage::add('custom', 'Message')
render($dismissible)Display all messages as Bootstrap alerts<?= FlashMessage::render() ?>
get()Retrieve and clear all messages$messages = FlashMessage::get()
has()Check if messages existif (FlashMessage::has())
clear()Clear all messages without retrievingFlashMessage::clear()
  1. Setting: Flash message is stored in $_SESSION['flash_messages']
  2. Redirect: User is redirected to another page (PRG pattern)
  3. Display: Next page renders messages using FlashMessage::render()
  4. Auto-clear: Messages are automatically removed after being retrieved
  5. Result: Message only appears once, then disappears
Flash TypeBootstrap ClassColor
successalert-successGreen
erroralert-dangerRed
infoalert-infoBlue
warningalert-warningYellow

Cause: SessionMiddleware not registered or sessions not working

Solution:

  • Verify SessionMiddleware is in config/middleware.php
  • Test that sessions work with the /test-session route
  • Check browser accepts cookies

Cause: Calling FlashMessage::render() multiple times

Solution:

  • Only call render() once per page
  • Check your layout/view for duplicate calls

Cause: render() not being called, so messages aren’t cleared

Solution:

  • Ensure FlashMessage::render() is in your view
  • Alternatively, call FlashMessage::get() or clear() manually

Cause: Bootstrap CSS not loaded

Solution:

  • Add Bootstrap CDN link to your view’s <head>:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">