Heinrich Schiller  25.07.2021 20:56

Eine Session-Unterst├╝tzung im mein Slim-Skeleton implementieren mit bryanjhv/slim-session

Ich habe vor einiger Zeit angefangen mich mit dem "Slim PHP micro framework" zu beschäftigen, was auch darin gemündet ist das ich mir ein eigenes Slim-Skeleton gebaut habe und diesen auch über Composer nutzen kann. Das wiederum war eher ein Zufall, den ich habe mich auch etwas mit Composer beschäftigt und zwar wie ich meine eigenen Bibliotheken in Composer integrieren kann. In meiner Einarbeitung in Slim, habe ich für jedes Slim-Projekt eine gleiche Struktur, immer und immer wieder aufgebaut. Das ist super, wenn man sich den ganzen Zusammenbau merken und analysieren möchte, kostet aber auch Zeit und wird irgendwann mal auch ziemlich öde. Dabei kam dann die Idee, wie und ob es funktionieren könnte mittels composer create-project Befehls eine von mir bereits geschriebene Struktur anlegen zu können und diese schlicht weiter nutzen. Symfony und Laravel können und nutzen es doch auch? Nach etwas rum probieren, hat das Ganze dann auch funktioniert und ich kann nun via composer create-project heinrichschiller/slim-skeleton --prefer-dist einfach ein neues Slim-Projekt beginnen. Das macht einen richtig Stolz :)

Nun, gegenüber dem offiziellen Slim-Skeleton ist mein Grundgerüst ziemlich klein und viele Dinge vom Haus aus nicht mit. Keine E-mail-Unterstützung, kein Templating, keine Sessions usw. Das ist so gewollt und wird sich in naher Zukunft auch nicht ändern. Was mich an Slim nämlich so fasziniert, ist seine eigentliche Größe und die Fähigkeit sich zu erweitern. Was fehlt, kann immer noch integriert werden und ich hatte schon einige Projekte wo ich schlicht nur das Grundgerüst und E-mail-Funktionalität gebraucht habe. Also habe ich mit composer ein neues Slim-Projekt erstellt und noch den PHPmailer dazu geholt und nach kurzer Arbeit, hatte ich ein schlichtes Kontakt-Formular das Emails versendet. Aber ich schweife mal wieder ab ... hier geht es mal um die Sessions.

Es gibt verschiedene Bibliotheken für Slim, wo man es um die Sessions erweitern kann. 2 davon wären zum Beispiel:

Hier geht es um die bryanjhv/slim-session und wie ich es bei mir integriere. Ich mache das nicht so oft und es ist etwas "kompliziert", weil die Original-Beispiele sich von meinem Grundgerüst unterscheiden. Ich kann dann später hier einfach reingucken und mich wieder orientieren, wie ich das mal gemacht habe ... so einfach ist das :)

Die original-Beschreibung verlinke ich hier, abgekürzt sieht es so aus:

Installation

Add this line to require block in your composer.json:

"bryanjhv/slim-session": "~4.0"

Or, run in a shell instead:

composer require bryanjhv/slim-session:~4.0

Usage

$app = \Slim\Factory\AppFactory::create();
$app->add(
  new \Slim\Middleware\Session([
    'name' => 'dummy_session',
    'autorefresh' => true,
    'lifetime' => '1 hour',
  ])
);

Helper class is available, which you can register globally or instantiate:

$container = new \DI\Container();

// Register globally to app
$container->set('session', function () {
  return new \SlimSession\Helper();
});
\Slim\Factory\AppFactory::setContainer($container);

That will provide $app->get('session'), so you can do:

$app->get('/', function ($req, $res) {
  // or $this->get('session') if registered
  $session = new \SlimSession\Helper();

  ...

  // Get session id
  $id = $this->session::id();

  return $res;
});

Die Installation macht man so wie beschrieben, das unterscheidet sich natürlich nicht. 

Benutzung

Um es erstmal zu testen, nimmt man diesen Code:

$app->add( 
    new \Slim\Middleware\Session([ 
       'name' => 'dummy_session', 
       'autorefresh' => true, 
       'lifetime' => '1 hour', ]) 
);

Und kopiert man im meinem Slim-Skeleton unter app/middleware zwischen addBodyParsingMiddleware() und addRoutingMiddleware(), ungefähr so:

$app->addBodyParsingMiddleware();

$app->add(
    new Session([
        'name' => 'dummy-session',
        'autorefresh' => true,
        'lifetime' => '1 hour'
    ])
);

$app->addRoutingMiddleware();

Dann geht es zur Systemweiten Integration:

$container->set('session', function () {
  return new \SlimSession\Helper();
});

Das Beispiel nutzt einen "einfachen" Container, ich verwende stattdessen den ContainerBuilder von PHP-DI und darum sieht es bei mir erstmal wie folgt aus. In der app/containers.php, zum Beispiel so:

use SlimSession\Helper;

return function (ContainerBuilder $builder) {
    $builder->addDefinitions([
        ...

        'session' => function () {
            return new Helper;
        },

        ...

Man kann das jetzt noch weiter ausbauen, eine zusätzliche Session-Klasse zum Kapseln, eine zusätzliche AuthMiddleware etc. aber jetzt geht es erstmal um einen Test, ab das auch funktioniert. Mein Slim-Skeleton hat schon 2 Beispiel routen, also teste ich das ganze unter routes/web.php, (aktivieren unter bootstrap/app.php nicht vergessen!), der Code schaut so aus:

return function (App $app) {
    $app->get('/', function (Request $request, Response $response, array $args = []): Response {
        $session = new SlimSession\Helper;

        $response->getBody()->write('Welcome to Slim PHP micro framework!: Session-ID = ' . $session->id());

        return $response;
    });
};

Mit $session = new SlimSession\Helper; holle ich mir eine neue Session, die ich mir mit $session->id() auf der Webseite anzeigen lasse. Wenn alles richtig gemacht wurde. So einfach lässt sich eine Slim-Anwendung in wenigen Schritten um eine Session-Unterstützung erweitern. Es geht natürlich auch mit session_start() usw. nur hier wurde der Code bereits von einem fleißigen Entwickler geschrieben und ich möchte hier erstmal nicht versuchen ein Rad neu zu erfinden.

Bis die Tage!