Lab Instructions: Implementing Flash Messages
Additional Resources
Section titled “Additional Resources”Overview
Section titled “Overview”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.
Learning Objectives
Section titled “Learning Objectives”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.
Prerequisites
Section titled “Prerequisites”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.
Lab Steps
Section titled “Lab Steps”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:
- Navigate to your
app/Helpers/directory - Create a new file named
FlashMessage.php - Copy and paste the following code:
<?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; }}- Implement all the TODO comments in the code above
- Save the file
What you need to implement:
success(),error(),info(),warning()methods - each should calladd()with the appropriate typeadd()method - stores flash messages in the sessionget()method - retrieves and clears flash messages from the sessionhas()method - checks if flash messages existclear()method - removes flash messages from the session
Already provided:
- The
render()method that generates Bootstrap alert HTML with XSS protection
Step 2: Create a Test Controller
Section titled “Step 2: Create a Test Controller”Objective: Create a controller to demonstrate flash message functionality.
Instructions:
- Navigate to your
app/Controllers/directory - Create a new file named
FlashDemoController.php - Implement a controller class that extends
BaseControllerwith 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
Responseobject
| Callback Method Name | What 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(), orFlashMessage::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
- Save the file
Step 3: Register Routes
Section titled “Step 3: Register Routes”Objective: Add routes for the flash message demo controller.
Instructions:
- Open your
app/Routes/web-routes.phpfile - Add the following import at the top:
use App\Controllers\FlashDemoController;- 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');- Save the file
Step 4: Create the Demo View
Section titled “Step 4: Create the Demo View”Objective: Create a view that displays flash messages and provides buttons to test each message type.
Instructions:
- Navigate to your
app/Views/directory - Create a new folder named
flash/ - Inside
flash/, create a file namedflashIndexView.php - Copy and paste the following code:
<!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>- 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
Step 5: Test Your Implementation
Section titled “Step 5: Test Your Implementation”Objective: Verify that flash messages work correctly.
Instructions:
- Start your development server (if not already running)
- Visit
http://localhost/[your-app-name]/flashin your browser - 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, 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
Understanding What You Built
Section titled “Understanding What You Built”FlashMessage Helper Methods
Section titled “FlashMessage Helper Methods”| Method | Description | Example |
|---|---|---|
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 type | FlashMessage::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 exist | if (FlashMessage::has()) |
clear() | Clear all messages without retrieving | FlashMessage::clear() |
How Flash Messages Work
Section titled “How Flash Messages Work”- Setting: Flash message is stored in
$_SESSION['flash_messages'] - Redirect: User is redirected to another page (PRG pattern)
- Display: Next page renders messages using
FlashMessage::render() - Auto-clear: Messages are automatically removed after being retrieved
- Result: Message only appears once, then disappears
Common Issues and Solutions
Section titled “Common Issues and Solutions”Issue 1: Messages Don’t Appear
Section titled “Issue 1: Messages Don’t Appear”Cause: SessionMiddleware not registered or sessions not working
Solution:
- Verify
SessionMiddlewareis inconfig/middleware.php - Test that sessions work with the
/test-sessionroute - Check browser accepts cookies
Issue 2: Messages Appear Multiple Times
Section titled “Issue 2: Messages Appear Multiple Times”Cause: Calling FlashMessage::render() multiple times
Solution:
- Only call
render()once per page - Check your layout/view for duplicate calls
Issue 3: Messages Persist After Refresh
Section titled “Issue 3: Messages Persist After Refresh”Cause: render() not being called, so messages aren’t cleared
Solution:
- Ensure
FlashMessage::render()is in your view - Alternatively, call
FlashMessage::get()orclear()manually
Issue 4: Bootstrap Styles Not Showing
Section titled “Issue 4: Bootstrap Styles Not Showing”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">