Benutzer-Werkzeuge

Webseiten-Werkzeuge


zf2self:zendsession

Skript & Tricks » ZF2 » ZendSession

ZF2: ZendSession

Problematisch, weil an dieser Stelle mal wieder sehr knapp dokumentiert, ist für mich an sich auch immer die Benutzung von Sessions im ZendFramework gewesen , weil ich nicht dahinter kam, wie die im Framework inbegriffene Klasse ZendSession genau funktioniert.

Einige Experimente und Zeit später hat es nun mal richtig Klick gemacht…

Am Ende bleiben wir Programmierer dann doch eben Sieger, nicht wahr? ;-)

Die Sessions teilen sich in zwei Bereiche auf:

  • Die Sessionverwaltung an sich
  • Die Session-Container

Die in allen Belangen konfigurierbare Sesssion an sich läuft am Ende sozusagen im Hintergrund und kann innerhalb der Anwendung noch in verschiedene Container aufgeteillt werden, die entweder einem bestimmten Zweck dienen oder die Informationen eines Bereiches schlicht vor anderen Bereichen verbergen.

Session-Konfiguration

Die Konfiguration findet am einfachsten in den Konfigurationsdateien des Frameworks statt und sie kennt alle Parameter der PHP-Session-Verwaltung.

Hier z.B. eine recht minimale Konfiguration einer Session, die in der global.php eingetragen ist:

'session_config'    => array(
        'name'          => 'EHTAB',
        'use_cookies'   => true,
        'cache_expire'  => 120,
 
    ),

Natürlich darf, am besten an derselben Stelle im service_manager-Bereich, nicht vergessen werden, den Zugang zu den Factory-Dateien der Session-Services zu erlauben und zu konfigurieren:

'service_manager'   => array(
        'factories'     => array(
            'ZendSessionConfig'     => 'Zend\Session\Service\SessionConfigFactory',
            'ZendSession'           => 'Zend\Session\Service\SessionManagerFactory',
        ),

Session starten

Um im Framework eine allgemeingültige Session zu etablieren, die sich nicht in jedem Modul wieder ändert (es sei denn wir wollen das so…) ist es am günstigsten den Start auch in das Startmodul der Anwendung zu schreiben, also hier in die Application/Module.php in die Methode onBootstrap():

$config = $e->getApplication()
            ->getServiceManager()
            ->get('Configuration');
 
        $sessionManager = $e->getApplication()->getServiceManager()->get('ZendSession');
        $sessionConfig  = $e->getApplication()->getServiceManager()->get('ZendSessionConfig');
        $sessionConfig->setOptions($config['session_config']);
        $sessionManager->setConfig($sessionConfig);
        $sessionManager->start();

Session in der Datenbank speichern

Um die Session so zu konfigureiren, dass sie in einer Datenbank-Tabelle gespeichert wird, ist etwas mehr Anlauf notwendig, so dass man hier am besten eine kleine Methode in die Module.php schreibt, die man im Aufruf von onBootstrap() dann ausführen lässt:

public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
        $this->bootstrapSession($e);
 
 
    }
 
public function bootstrapSession($e)
    {
        $db = $e->getApplication()->getServiceManager()->get('DbService');
 
        $sessionGateway = new TableGateway('ehtab__session', $db->setNewAdapter('web_apps'));
        $options = new DbTableGatewayOptions();
        $saveHandler = new DbTableGateway($sessionGateway, $options);
 
        $session = $e->getApplication()
        ->getServiceManager()
        ->get('ZendSession');
 
        $session->setSaveHandler($saveHandler);
        $session->setName('EHTAB');
        $session->start();
        //Debug::dump($session->getId());
 
    }

Die erste Zeile in der bootstrapSession() ist der Aufruf meines persönlichen DbService, den ich mir für meine DB-Arbeit ausgedacht habe. Grundsätzlich wird hier schlicht eine Datenbank-Verbindung zur in der Config konfigurierten Datenbank unter dem Alias web_apps hergestellt.

Die nächsten drei Zeilen stellen eine TableGateway der Tabelle ehtab_session zur Verfügung, welches als saveHandler für die Session definiert wird.

Der letzten beiden Abschnitte starten schlicht die Session.

In diesem Beispiel fehlt jetzt das Auslesen der Config nach weiteren Parametern mittels ZendSessionConfig, wie im oberen Beispiel.

Zum einen reicht mir an der Stelle die einfach Grundkonfiguration der Session, zum Anderen verursacht das Aufrufen von ZendSessionConfig zumindest bei mir seltsame Nebeneffekte, denen ich, mangels ausreichender Doku und Phantasie, nicht folgen kann.

Natürlich fehlt jetzt noch die Tabelle, die in der Datenbank die Sessions für uns speichert:

CREATE TABLE `ehtab__session` (
	`id` VARCHAR(52) NOT NULL,
	`name` VARCHAR(52) NULL DEFAULT NULL,
	`data` TEXT NULL,
	`modified` INT(11) NULL DEFAULT NULL,
	`lifetime` INT(11) NULL DEFAULT NULL,
	PRIMARY KEY (`id`)
)
COMMENT='Gespeicherte Sessions'
COLLATE='utf8_general_ci'
ENGINE=Aria
;

Ich benutze MariaDB, die Engine Aria kann natürlich auch MyISAM heißen.

Container

Ein Container funktioniert nun quasi wie eine Sub-Session und kann sozusagen an beliebiger Stelle in der Anwendung erstellt und benutzt werden, offenbar (hab ich noch nicht gestestet) auch mehrere nebeneinander her.

   $meinContainer = new Container('meinContainer')
   $meinContainer->zaehler = $meinContainer->zaehler +1;
   echo $meinContainer->zaehler;

Das Beispiel zeigt das Errichten eines Container und das Abspeichern eines Wertes darin, der in diesem Fall mit jedem Seitenaufruf größer wird, bevor er ausgegeben wird.

Daneben hat der Container noch die Möglichkeit über den SessionManager die Konfiguration der Session zu beeinflussen und bringt Prüffunktionen für die in der Session enthaltenen Werte mit:

    $sm = $meinContainer->getManager();
    $sm->destroy();
 
    if ($meinContainer->offsetExists('zaehler')):
       echo $meinContainer->getOffset('zaehler');
    else:
       $meinContainer->offsetSet('zaehler') = 1;
    endif;

Letzlich also nur ein einfacherer Zugang in die Session, als mit nacktem PHP 8-)

zf2self/zendsession.txt · Zuletzt geändert: 2016/06/25 17:31 von thefan1968