Source of packages/Combie/Session/Session.php
<?php
/**
 *
 *
 * @author Combie <uli@combie.de>
 * @version $Id$
 * @package Combie
 * @subpackage Session
 */
namespace Combie\Session;
// eine auf Sicherheit optimierte singleton Klasse
/**
 *
 *
 * @package Combie
 * @subpackage Session
 */
class Session
{
  private static $sessionkey = 'SingletonSessionClass';
  
  private $uniquekey = '';
  private $regenerate = 0;
  private $sanity = '';
  private $sessionvars = array();
  
  private function __construct()
  {
      $this->uniquekey = md5(serialize($_SERVER).microtime());
      output_add_rewrite_var('sk',$this->uniquekey);
      $this->cleanup();
  }
  private function makesanity()
  {
      $sanity = '';
      $sanity .= isset($_SERVER['HTTP_ACCEPT'])         ?$_SERVER['HTTP_ACCEPT']         :'';
      $sanity .= isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])?$_SERVER['HTTP_ACCEPT_LANGUAGE']:'';
      $sanity .= isset($_SERVER['HTTP_ACCEPT_CHARSET']) ?$_SERVER['HTTP_ACCEPT_CHARSET'] :'';
      $sanity .= isset($_SERVER['HTTP_ACCEPT_ENCODING'])?$_SERVER['HTTP_ACCEPT_ENCODING']:'';
      return md5($sanity) ;
  }
  
  public function cleanup()
  {
        $this->sanity = $this->makesanity();
        $this->sessionvars = array();
  }
  public function __wakeup()
  {
      if(
          (!isset($_REQUEST['sk']) || $_REQUEST['sk']!=$this->uniquekey)
         ||    ($this->sanity !== $this->makesanity())
        )
      {
        $this->cleanup();
      }
      //throw ;
      output_add_rewrite_var('sk',$this->uniquekey);
      foreach($this->sessionvars as $key => $eintrag)
      {
        if($eintrag['lifetime'] > 0 && $eintrag['lifetime']+$eintrag['timestamp']<time())
        {
          unset($this->sessionvars[$key]);
        }
      }
  }
  public function __sleep()
  {
      return array('uniquekey','sessionvars','sanity');
  }
  
  public function set($key,$value,$lifetime=0)
  {
      $this->sessionvars[$key] = array( 'timestamp' => time(),
                                        'lifetime'  => $lifetime,
                                        'value'     => $value );
  }
  
  public function get($key)
  {
      if(isset($this->sessionvars[$key]))
      {
          $this->touch($key);
          return $this->sessionvars[$key]['value'];
      }
      new Exception('Sessiondata not found',1);
  }
  
  public function has($key)
  {
      if(!empty($this->sessionvars[$key]))
      {
        $this->touch($key);
        return TRUE;
      }
        
      else FALSE;
      
  }
  public function touch($key)
  {
      $this->sessionvars[$key]['timestamp'] = time();
  }
  private function regenerate()
  {
    if($this->regenerate < 1)
    {
      if(!session_regenerate_id())
         new Exception('Session regenerate fault',1);
    }
    $this->regenerate++;
  }
  public static function getInstance()
  {
    if('' == session_id()) session_start();
    $selbst = __CLASS__;
    if(empty($_SESSION[self::$sessionkey]))
        $_SESSION[self::$sessionkey] = new $selbst;
    if($_SESSION[self::$sessionkey] instanceof $selbst)
    {
      $_SESSION[self::$sessionkey]->regenerate();
      return $_SESSION[self::$sessionkey];
    }
    throw new Exception('Session Typemismatch');
  }
  private function __clone() // clonen verboten
  {
    throw new Exception('Diese Sessionklasse darf nicht geklont werden');
  }
}
?>