Slim4 & Flash. Flash message stays empty

Tried to search in other topics, but could not find an solution.

I try to create a Flash Message (same steps as on Slim 3). A session is started and works.
But somehow I can’t set a message.

App.php:

    session_start();

use Slim\Views\Twig;
use Slim\Factory\AppFactory;
use Slim\Views\TwigExtension;
use Slim\Psr7\Factory\UriFactory;

require_once __DIR__ . '/../vendor/autoload.php';

$container = new DI\Container();
AppFactory::setContainer($container);
$app = AppFactory::create();


$container->set('settings', function () {
    return [
        'app' => [
            'name' => getenv('APP_NAME')
        ]
    ];
});

$container->set('flash', function($container) use ($app) {
    return new \Slim\Flash\Messages();
});
// Undefined property: App\Controllers\HomeController::$flash

$container->set('view', function ($container) use ($app) {

    $twig = new Twig(__DIR__ . '/../resources/views', [
        'cache' => false
    ]);

    return $twig;
});

// Route File
require_once __DIR__ . '/../routes/web.php';

Routefile:
use App\Controllers\HomeController;

$app->get('/', HomeController::class . ':index');
$app->get('/translate', HomeController::class . ':translateExample');
$app->get('/flash', HomeController::class . ':flashMessage');
$app->get('/language/{lang}', HomeController::class . ':switchLanguage');

HomeController, flashMessage function:

     public function flashMessage(Request $request, Response $response, $args)
    {
           // Tried
          // $this->flash->addMessage('success', $array);
          // $this->c->flash->addMessage('success', $array);
          // Undefined property: App\Controllers\HomeController::$flash

         $mess = $this->c->get('flash')->addMessage('Test', 'This is a message');
         dd($mess); // (Temp. for testing if something happens)

    // Redirect
    return $response->withStatus(302)->withHeader('Location', '/translate');

The array ($mess) is and stays empy (null).

Not sure if the backticks are part of your code or added for display. But, if part of your code, remove them.

    return new \Slim\Flash\Messages();

in HomeController we need to see the constructor to know how the message should be created in flashMessage().

Hi @darkalchemy,

I removed the typo, it was only on the forum, not in the code.
Also placed more detailed information in the App.php part of previous post.

Maybe I’m missing it, but I don’t see the constructor for the HomeController

Undefined property: App\Controllers\HomeController::$flash

What you are trying is not supported by Slim 4 anymore.

1 Like

Got it working by testing Slim 3. In there the Flash message is also null.
Had to adjust some settings, not sure if this is de best method?

App.php inserted the following (Twig / Controller)
$twig->getEnvironment()->addGlobal('flash', $container->get('flash'));

In the twig template i can now call the function.
{{ flash.getMessage('info') | first }}

So it works, but not sure if this is a good approach.

en Slim 4
Como seria?

The slim/flash component should work with Slim 4. Make sure that the session is started. The problem is that the container definition requires a running session. But there is a trick to make it work in combination with a IoC container.

composer require slim/flash

Add the container definition:


use Slim\Flash\Messages;
// ...

return [
    // ...
    Messages::class => function () {
        // Don't use $_SESSION here, because the session is not started at this moment.
        // The middleware changes the storage.
        $storage = [];
        return new Messages($storage);
    },
];

Add a custom Middleware to pass the session storage, e.g. in src/Middleware/SlimFlashMiddleware.php:

<?php

namespace App\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Flash\Messages;

final class SlimFlashMiddleware implements MiddlewareInterface
{
    /**
     * @var Messages
     */
    private $flash;

    public function __construct(Messages $flash)
    {
        $this->flash = $flash;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // Set new flash message storage
        $this->flash->__construct($_SESSION);

        return $handler->handle($request);
    }
}

The session must be started first.
To prevent an error like Fatal error: Uncaught RuntimeException: Flash messages middleware failed. Session not found. add the SessionFlashMiddleware before the SessionMiddleware.

<?php

use App\Middleware\SessionFlashMiddleware;
use App\Middleware\SessionMiddleware;

// ...

$app->add(SessionFlashMiddleware::class); // <--- here

// Start the session
$app->add(SessionMiddleware::class); 

Getting Errors like Flash messages middleware failed. Session is not found issue.
Can you share the class detail of SessionFlashMiddleware & SessionMiddleware?
Also, adding SlimFlashMiddleware in the middleware.php file like $app->add(SlimFlashMiddleware::class); is correct?