Skip to content

Lab 4: 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
{
// TODO: Call the add() method with 'success' as the type
}
/**
* Add an error message.
*/
public static function error(string $message): void
{
// TODO: Call the add() method with 'error' as the type
}
/**
* Add an info message.
*/
public static function info(string $message): void
{
// TODO: Call the add() method with 'info' as the type
}
/**
* Add a warning message.
*/
public static function warning(string $message): void
{
// TODO: Call the add() method with 'warning' as the type
}
/**
* Add a flash message of any type.
*/
public static function add(string $type, string $message): void
{
// TODO: Check if $_SESSION[self::FLASH_KEY] is not set
// If not set, initialize it as an empty array
// TODO: Add a new message to the $_SESSION[self::FLASH_KEY] array
// The message should be an associative array with 'type' and 'message' keys
}
/**
* Get all flash messages and clear them.
*/
public static function get(): array
{
// TODO: Retrieve all messages from $_SESSION[self::FLASH_KEY]
// Hint: Use the null coalescing operator (??) to default to an empty array
// TODO: Remove the flash messages from the session using unset()
// TODO: Return the retrieved messages
}
/**
* Check if there are any flash messages.
*/
public static function has(): bool
{
// TODO: Check if $_SESSION[self::FLASH_KEY] exists and is not empty
// Hint: Use the empty() function
}
/**
* Clear all flash messages without retrieving them.
*/
public static function clear(): void
{
// TODO: Remove the flash messages from the session using unset()
}
/**
* Render all flash messages as Bootstrap alerts.
*
* This method is provided for you as it involves complex HTML generation.
*/
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. Implement all the TODO comments in the code above
  2. Save the file

What you need to implement:

  • success(), error(), info(), warning() methods - each should call add() with the appropriate type
  • add() method - stores flash messages in the session
  • get() method - retrieves and clears flash messages from the session
  • has() method - checks if flash messages exist
  • clear() method - removes flash messages from the session

Already provided:

  • The render() method that generates Bootstrap alert HTML with XSS protection

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:

  • 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(), set 2-3 different flash messages before redirecting
  1. Save the file

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 app/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:
app/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 are displayed only once and are automatically cleared from the session after being rendered.
</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” → Multiple alerts of different types

Expected Behavior:

  • Messages appear at the top of the page after redirect
  • Messages have appropriate colors (success=green, error=red, info=blue, warning=yellow)
  • 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