Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flash Laravel Package

slim/flash

slim/flash adds flash messaging to Slim Framework applications, storing short-lived messages in the session so they survive a redirect and display once on the next request. It offers a simple PSR-7-friendly API, middleware integration, and multiple message levels.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer and pin the version — the features below landed in 0.4.0:

composer require slim/flash:^0.4

This is a Slim 3 package. Before anything else you need a live PHP session, because Slim\Flash\Messages reads and writes $_SESSION directly (default key slimFlash). Start the session during bootstrap, before the container resolves the flash service:

session_start();

$app = new \Slim\App();
$container = $app->getContainer();

$container['flash'] = function () {
    return new \Slim\Flash\Messages();
};

Then use $this->flash inside your route callables (Slim 3 auto-binds Route to the container, so $this->flash resolves the service).

The first use case you will hit is Post/Redirect/Get. In the POST handler, add a message and redirect; in the GET handler, read it back:

$app->post('/contact', function ($request, $response) {
    // ... validate / persist
    $this->flash->addMessage('success', 'Thanks, we got your message.');
    return $response->withRedirect('/contact');
});

$app->get('/contact', function ($request, $response) {
    return $this->view->render($response, 'contact.twig', [
        'flash' => $this->flash->getMessages(),
    ]);
});

Look at Slim\Flash\Messages first — it is the whole package. The relevant surface is now addMessage(), getMessage(), getMessages(), getFirstMessage(), hasMessage(), clearMessage(), and clearMessages().

Implementation Patterns

PRG flash in a middleware-friendly way. Keep the container registration (not $app->add(new Messages())) if you need access from both routes and views. Adding it as middleware also works — it implements Slim 3's middleware interface — but then you still need a reference to the instance for reads, so the container registration is the practical choice.

Grouped keys for UI states. Use distinct keys (success, error, info) and iterate them in your template. This maps cleanly onto Bootstrap/alert markup:

foreach ($this->flash->getMessages() as $type => $messages) {
    foreach ($messages as $msg) {
        // render alert$type
    }
}

One-message buckets with getFirstMessage() (0.4.0). When a key holds a single message — a login error, a one-line confirmation — skip the nested loop:

$error = $this->flash->getFirstMessage('error');
// null (or your default) when nothing was flashed

This is the cleanest read for banners where only the first message matters; the per-key array form still applies if you deliberately stack several.

Clearing precisely with clearMessage() (0.4.0). clearMessages() nukes every bucket; clearMessage($key) drops a single key and leaves the rest intact. Use it when one region of the page consumes success while error must survive for another partial, or when a handler renders and re-renders the same key in one request.

Custom storage key (0.4.0). The session key is no longer hard-wired to slimFlash. Pass your own as the second constructor argument:

$container['flash'] = function () {
    return new \Slim\Flash\Messages($_SESSION, 'app_flash');
};

Two reasons to reach for this: avoiding collisions with other packages that squat on slimFlash, and running two independent flash bags in the same app (e.g. admin_flash for the back office, app_flash for the storefront) so a shared session never leaks messages across contexts. Decide the key once, at construction — it is the $_SESSION subkey used for every subsequent read and write, so a second instance with a different key will never see the first one's messages.

Twig integration. Expose flash as a view variable in a global middleware, or pass it explicitly per route. If you use slim/twig-view, add it to the view's getEnvironment()->addGlobal() so partials can render alerts without touching every controller.

Reading a single message. Use hasMessage($key) then getMessage($key, $default) when you only care about one bucket (e.g. a login error) and want an explicit fallback rather than a null check.

Testing. The constructor accepts a storage argument by reference, so you can bypass $_SESSION in unit tests. Remember to assign the array to a variable first (see Gotchas):

$storage = [];
$flash = new \Slim\Flash\Messages($storage);
$flash->addMessage('test', 'hi');
$this->assertTrue($flash->hasMessage('test'));
$this->assertSame('hi', $flash->getFirstMessage('test'));

Add a case with a custom key to prove your two-bag setup stays isolated.

Integration with session middleware. If you use a Slim 3 session middleware (e.g. slim/session or a custom one), start it early enough that session_start() has run before the container factory for flash executes. The flash object binds $_SESSION by reference at construction time — if it is constructed before the session exists, it throws.

Clearing. Call clearMessages() explicitly if you render flashes in a partial and want to guarantee they aren't shown twice in the same request lifecycle; prefer clearMessage($key) when only one bucket has been consumed.

Gotchas and Tips

  • Slim 3 only. The last release (0.4.0) is from 2017, a year and a half before Slim 4. This package will not drop into a Slim 4 app without adaptation; Slim 4 has no bundled flash implementation, so plan on a small custom middleware or a maintained community replacement.
  • The session must exist first. Constructing Messages without a started session raises a RuntimeException('Session not started'). Call session_start() (or your session middleware) before the container resolves flash.
  • session_start() placement matters. Because the constructor captures $_SESSION by reference, session_start() must run during bootstrap — not lazily inside a route. Calling it after the service is constructed leaves the flash bound to an empty array.
  • Custom key is set once, at construction. There is no setter. If you later read $_SESSION['slimFlash'] while the app writes app_flash (or vice versa), you will debug a phantom. Keep the key in config and use the same value everywhere the service is built.
  • Mixed keys in one $_SESSION. Two instances with different keys coexist happily, but clearMessages() only clears its own bag — it will not wipe another instance's messages. That is usually what you want; do not assume it is a global session flush.
  • It writes to $_SESSION. Messages survive across requests until read/cleared, so a session_regenerate_id() or session_destroy() (e.g. on logout) silently drops pending flash data. Verify flash still works after login/logout flows.
  • Read-once semantics. Messages are intended for the next request. Reading them does not automatically clear them in all versions — call clearMessages() if you re-render in the same request or you will see duplicates. getFirstMessage() does not remove the message it returns.
  • No addMessageNow behavior distinction in older docs. If you need a message on the current request, do not rely on flash; assign it directly to the view instead.
  • Unmaintained. Last release 2017, zero tracked dependents. The code is tiny and stable, but pin the version in composer.json and treat it as frozen. It generally runs fine on PHP 8, but you own any compatibility fixes.
  • Reference parameter quirk. new Messages($storage) requires $storage to be a variable; you cannot pass an array literal because the constructor parameter is by-reference. This trips up tests — and is easy to get wrong when you add the new second argument.
  • Stateless APIs. Do not use this in a JSON/API context — it hard-depends on PHP sessions and redirects. It is a server-rendered HTML convenience.
  • Debugging tip. Inspect $_SESSION['slimFlash'] (or your custom key) directly when messages "disappear." The most common causes are a missing session_start(), a mismatched storage key between two service definitions, the session being regenerated mid-flow, or getMessages() being called before addMessage() in the request order.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums