SessionHandler - Sessions in einer Datenbank

B

Bgag

Hallo!
Da ich mich gerade mit dem Thema Benutzer- und Rechteverwaltung beschäftige, habe ich mich auch mit dem verwandten Thema Sessions auseinandergesetzt. Da ich vor wenigen Tagen im PHP Manual auf die Funktion session_set_save_handler() gestoßen bin, habe ich mir überlegt anstatt der im Manual vorgestellten Funktionen eine Klasse zu schreiben, die es mir ermöglich Sessions in einer Datenbank zu speichern. Ich habe also die Funktionen in eine Klasse gepackt und mit Datenbank An- und Abfragen gefüllt. Dabei greife ich auf den Datenbank-Zugriff via MySQLi zurück.

Im großen und ganzen ist mir die Klasse, denke ich, auch ganz gut gelungen. Um das ganze zu verwenden arbeitet man eigentlich ganz normal mit den Sessions. Man muss zuvor nur eine Instanz der Klasse erzeugen.

Nun ist allerdings ein kleines Problem aufgetreten. Die Sessions werden garnicht in der Datenbank gespeichert, sondern weiterhin in Dateien. Im nachfolgenden ein einfacher Aufruf.

PHP:
/* make sure session started */
new SessionHandler( $mysqli );
        
if( !isset($_SESSION['user']) )
{
   echo "Sie sind nicht eingeloggt!\n";
}
        
/* create a test session */
if( !isset($_SESSION['user']) && !isset($_SESSION['role']) )
{
   $_SESSION['user'] = 'hannes';
   $_SESSION['role'] = 'visitor';
}
        
if( isset($_SESSION['user']) )
{
    echo "Sie sind nun eingeloggt!\n";
}
        
if( $this->accessManager->checkPermissionsByRole($_SESSION['role'], 'view', 'user_admin') )
{
    echo "Welcome " . $_SESSION['user'] . "!\n";
}
        
else
{
    echo "Access denied!";
}

Die Ausgabe funktioniert, es werden also Sessions erzeugt, jedoch werden diese nicht in der Datenbank gespeichert. Diese ist leer. Hat jemand eine Idee, woran das liegen kann? Hatte an der Klasse noch eine Winzigkeit geändert (daran liegt es nicht), daher findet ihr die neue Version unten.

MfG, Andy

SessionHandler.php
PHP:
<?php

/*
 * Class SessionHandler
 * 
 * The SessionHandler class imlements all methods to use a 
 * database based session management instead of using text files. 
 * This has the benefit thatt all session data can be accessed
 * at a central place. This class is supported since the PHP version 5.0.5 
 * because it uses the register_shutdown_function() function to ensure that 
 * all session values are stored before the PHP representation is destroyed.
 * 
 * @package SessionHandler
 * @version 0.1
 * @author Andreas Wilhelm <Andreas2209@web.de>
 * @copyright Andreas Wilhelm 
 * @link http://avedo.net
 */  
class SessionHandler
{
	/**
	 * @var mysqli $mysqli The MySQLi object that is used to access the database
	 * @access private
	 */
	private $mysqli = null;

	/**
	 * Sets the user-level session storage functions which are used 
	 * for storing and retrieving data associated with a session.
	 *
	 * @access public
	 * @param mysqli $mysqli The MySQLi object that is used to access the database
	 * @return void
	 */
	public function __construct(mysqli $mysqli)
	{
		/* assign the mysqli object */
		$this->mysqli = $mysqli;

		ini_set('session.save_handler', 'user');
	
		/* set session handler to the class methods */
		session_set_save_handler(
			array(&$this, '_open'),
			array(&$this, '_close'),
			array(&$this, '_read'),
			array(&$this, '_write'),
			array(&$this, '_destroy'),
			array(&$this, '_gc')
		);
		
		/* start a new session */
		session_start();

		/* make sure that the session values are stored */
		register_shutdown_function('session_write_close');
	}
	
	/**
	 * Is called to open a session. The method 
	 * does nothing because we do not want to write
	 * into a file so we doesn't need to open one.
	 *
	 * @access public
	 * @param String $save_path The save path
	 * @param String $session_name The name of the session
	 * @return Boolean
	 */
	public function _open($save_path, $session_name)
	{
		return true;
	}
	
	/**
	 * Is called when the reading in a session is 
	 * completed. The method calls the garbage collector. 
	 *
	 * @access public
	 * @return Boolean
	 */
	public function _close()
	{
		/* call the garbage collector */
		$this->_gc(100);
		
		return true;
	}
	
	/**
	 * Is called to read data from a session.
	 *
	 * @access public
	 * @access Integer $id The id of the current session
	 * @return Mixed
	 */
	public function _read($id)
	{
		/* create a query to get the session data */
		$select = "SELECT 
				* 
			FROM 
				`sessions` 
			WHERE 
				`sessions`.`id` = '" . $id . "'
			LIMIT 1;";
		
		/* send select statement */
		$result = $this->mysqli->query($select);
		
		/* check for result */
		if( !$result )
		{
			throw new Exception("MySQL error while performing query.");
		}
		
		/* a session was found */
		if( $result->num_rows > 0 )
		{
			/* get assoc array */
			$ret = $result->fetch_assoc();
		
			return $ret["value"];
		}
		
		/* no session found */
		return '';
	}
	
	/**
	 * Writes data into a session rather 
	 * into the session record in the database.
	 *
	 * @access public
	 * @access Integer $id The id of the current session
	 * @access String $sess_data The data of the session
	 * @return Boolean
	 */
	public function _write($id, $sess_data)
	{
		/* check if some data was given */
		if( $sess_data == null )
		{
			return true;
		}
	
		/* query to update a session */
		$update = "UPDATE 
				`sessions` 
			SET 
				`sessions`.`last_updated` = '" .time() . "', 
				`sessions`.`value` = '" . $sess_data . "' 
			WHERE 
				`sessions`.`id` = '" . $id . "';";

		/* send select statement */
		$result = $this->mysqli->query($update);
		
		/* database error */
		if( $result === false )
		{
			return false;
		}
		
		/* current session was updated */
		if( $this->mysqli->affected_rows > 0 )
		{
			return true;
		}
		
		/* session does not exists create insert statement */
		$insert = "INSERT INTO 
				`sessions` 
				(id, last_updated, start, value) 
			VALUES 
				('" . $id . "', '" . time() . "', '" . time() . "', '" . $sess_data . "');";

		/* send insert statement */
		$result = $this->mysqli->query($insert);
		
		return $result;
	}
	
	/**
	 * Ends a session and deletes it.
	 *
	 * @access public
	 * @access Integer $id The id of the current session
	 * @return Boolean
	 */
	public function _destroy($id)
	{
		/* create a query to delete a session */
		$delete = "DELETE FROM 
				`sessions` 
			WHERE 
				`sessions`.`id` = '" . $id . "';";
				
		/* send delete statement */
		$result = $this->mysqli->query($delete);
		
		return $result;
	}
	
	/**
	 * The garbage collector deletes all sessions from the database 
	 * that where not deleted by the session_destroy function.
	 * so your session table will be stay clean.
	 *
	 * @access public
	 * @access Integer $maxlifetime The maximum session lifetime
	 * @return Boolean
	 */
	public function _gc($maxlifetime)
	{
		/* period after that a session pass off */
		$maxlifetime = strtotime("-20 minutes");
		
		/* delete statement */
		$delete = "DELETE FROM 
				`sessions` 
			WHERE 
				`sessions`.`last_updated` < '" . $maxlifetime . "';";

		/* send delete statement */
		$result = $this->mysqli->query($delete);
		
		return $result;
	}
}

?>
 
Zuletzt bearbeitet von einem Moderator:
Danke für deine schnelle Antwort. Du meinst an die Funktion session_set_save_handler? Ja hab ich, aber das hilft nichts. Er scheint im übrigen auch die Methoden aufzurufen. Habe einfach mal ne Ausgabe in der write bzw. read Methode gemacht.
 
Danke für deine Hilfe. Der Fehler lag im Endeffekt an der Typo (Asche auf mein Haupt). Läuft aber jetzt. Habe noch ein paar Dinge bei den Abfragen geändert. Habe die neue Version oben hochgeladen. Danke nochmals.

MfG, Andy
 
Zurück