<?php 
/** 
 * oSessionException extends Exception 
 * @author johan <[email protected]> 
 * @version 20061205 
 * 
 */ 
class oSessionException extends Exception { 
 
    /** 
     * Exception messages 
     * 
     */ 
    const NAME_NOT_ALPHANUMERIC = '{__NAME__} is not a valid session name: session name must be alphanumeric'; 
    const XML_FILE_NOT_EXISTS = '{__FILE__} has not been found'; 
    const XML_LOADING_FAILED = 'Failed to load {__FILE__}'; 
    const XML_EMPTY = 'XML configuration is empty'; 
    const KEY_NOT_EXISTS = '{__KEY__} is not a valid key'; 
    const TYPE_NOT_VALID = '{__TYPE__} is not a valid type for {__KEY__}, must be {__VALIDTYPE__}'; 
 
    /** 
     * Constructor 
     * Calls Exception constructor 
     * 
     * @param string $sMsg 
     * @param integer $iCode 
     */ 
    public function __construct ($sMsg, $iCode = 0) { 
        parent::__construct ($sMsg, $iCode); 
    } 
} 
 
/** 
 * oConf 
 * @author johan <[email protected]> 
 * @version 20061205 
 * 
 */ 
class oConf { 
 
    /** 
     * Array of configuration 
     * 
     * @var array 
     */ 
    protected $aConf; 
 
    /** 
     * Read the xml configuration file and fills the aConf property with its contents 
     * 
     * @param string $sConfFileName (xml configuration filename) 
     */ 
    protected function setConf ($sConfFileName) { 
        if (!file_exists ($sConfFileName)) { 
            throw new oUserException (str_replace ('{__FILE__}', $sConfFileName, oSessionException::XML_FILE_NOT_EXISTS)); 
        } 
        if (!($oXml = @simplexml_load_file ($sConfFileName)) instanceof SimpleXMLElement) { 
            throw new oUserException (str_replace ('{__FILE__}', $sConfFileName, oSessionException::XML_LOADING_FAILED)); 
        } 
        foreach ($oXml -> children () as $oNode) { 
            if (empty ($oNode)) { 
                throw new oUserException (self::XML_EMPTY); 
            } 
            $this -> aConf[(string)dom_import_simplexml($oNode) -> tagName] = (string)$oNode['type']; 
        } 
        $this -> bHasConf = true; 
    } 
 
    /** 
     * Gets the configuration 
     * 
     * @return array 
     */ 
    public function getConf () { 
        if (true === $this -> bHasConf) { 
            return $this -> aConf; 
        } 
        return null; 
    } 
} 
 
/** 
 * oSessionIterator implements Iterator 
 * @author johan <[email protected]> 
 * @version 20061205 
 * 
 */ 
class oSessionIterator implements Iterator { 
 
    /** 
     * Array of session keys 
     * 
     * @var array 
     */ 
    private $aKeys; 
 
    /** 
     * current key 
     * 
     * @var mixed 
     */ 
    private $mKey; 
 
    /** 
     * oSession Iterator 
     * 
     * @var oSession object 
     */ 
    private $it; 
 
    /** 
     * Constructor 
     * Sets some parameters 
     * 
     * @param oSession $it 
     */ 
    public function __construct (oSession $it) { 
        $this -> it = $it; 
        $this -> aKeys = $this -> it -> getKeys (); 
    } 
 
    /** 
     * Reset the array of keys and sets current key 
     * 
     */ 
    public function rewind () { 
        $this -> mKey = reset ($this -> aKeys); 
    } 
 
    /** 
     * Returns current key 
     * 
     * @return mixed 
     */ 
    public function key () { 
        return $this -> mKey; 
    } 
 
    /** 
     * Returns current value 
     * 
     * @return mixed 
     */ 
    public function current () { 
        if (isset ($this -> it[$this -> mKey])) { 
            return $this -> it[$this -> mKey]; 
        } 
        return null; 
    } 
 
    /** 
     * Gets next key 
     * 
     */ 
    public function next () { 
        $this -> mKey = next ($this -> aKeys); 
    } 
 
    /** 
     * Checks if current key is valid 
     * 
     * @return boolean 
     */ 
    public function valid () { 
        if (isset ($this -> it[$this -> mKey])) { 
            return true; 
        } 
        return false; 
    } 
} 
 
/** 
 * oSession extends oConf implements IteratorAggregate, ArrayAccess, Countable 
 * greatly inspired by PRADO framework <http://www.pradosoft.com/> 
 * @author johan <[email protected]> 
 * @version 20061205 
 * 
 */ 
class oSession extends oConf implements IteratorAggregate, ArrayAccess, Countable { 
 
    /** 
     * Is the oSession initialized or not 
     * 
     * @var boolean 
     */ 
    private $bIsStarted = false; 
 
    /** 
     * oSession has a configuration file or not 
     * 
     * @var boolean 
     */ 
    protected $bHasConf = false; 
 
    /** 
     * Constructor 
     * Checks configuration if any 
     * 
     * @param string $sConf Configuration filename 
     */ 
    public function __construct ($sConf = null) { 
        if (!is_null ($sConf)) { 
            $this -> setConf ($sConf); 
        } 
    } 
 
    /** 
     * Sets a new configuration file 
     * 
     * @param string $sConfFileName Configuration filename 
     */ 
    public function setNewConf ($sConfFileName) { 
        $this -> setConf ($sConfFileName); 
    } 
 
    /** 
     * Returns if oSession has a configuration or not 
     * 
     * @return boolean 
     */ 
    public function hasConf () { 
        return $this -> bHasConf; 
    } 
 
    /** 
     * Starts a session 
     * 
     */ 
    public function open () { 
        if (false === $this -> bIsStarted) { 
            $this -> bIsStarted = true; 
            session_start (); 
        } 
    } 
 
    /** 
     * Checks if an offset exists 
     * ArrayAccess method 
     * 
     * @param mixed $mKey 
     * @return boolean 
     */ 
    public function offsetExists ($mKey) { 
        if (true === $this -> bIsStarted && isset ($_SESSION[$mKey])) { 
            return true; 
        } 
        return false; 
    } 
 
    /** 
     * Gets an offset 
     * ArrayAccess method 
     * 
     * @param mixed $mKey 
     * @return mixed 
     */ 
    public function offsetGet ($mKey) { 
        if (true === $this -> bIsStarted && isset ($_SESSION[$mKey])) { 
            return $_SESSION[$mKey]; 
        } 
        return null; 
    } 
 
    /** 
     * Sets an offset if valid (if there is a configuration) 
     * ArrayAccess method 
     * 
     * @param mixed $mKey 
     * @param mixed $mVal 
     */ 
    public function offsetSet ($mKey, $mVal) { 
        if (true === $this -> bHasConf) { 
            if (!isset ($this -> aConf[$mKey])) { 
                throw new oSessionException (str_replace ('{__KEY__}', $mKey, oSessionException::KEY_NOT_EXISTS)); 
            } 
            if (($sType = gettype ($mVal)) !== $this -> aConf[$mKey]) { 
                throw new oSessionException (str_replace (array ('{__TYPE__}', '{__KEY__}', '{__VALIDTYPE__}'), array ($sType, $mKey, $this -> aConf[$mKey]), oSessionException::TYPE_NOT_VALID)); 
            } 
        } 
        $_SESSION[$mKey] = $mVal; 
    } 
 
    /** 
     * Unset an offset 
     * ArrayAccess method 
     * 
     * @param mixed $mKey 
     */ 
    public function offsetUnset ($mKey) { 
        unset ($_SESSION[$mKey]); 
    } 
 
    /** 
     * Returns the size of the current session 
     * Countable method 
     * 
     * @return integer 
     */ 
    public function count () { 
        if (true === $this -> bIsStarted) { 
            return count ($_SESSION); 
        } 
        return null; 
    } 
 
    /** 
     * Get the iterator of IteratorAggregation 
     * IteratorAggregate method 
     * 
     * @return Iterator 
     */ 
    public function getIterator () { 
        if (true === $this -> bIsStarted) { 
            return new oSessionIterator ($this); 
        } 
        return new ArrayIterator (array ()); 
    } 
 
    /** 
     * Destroy current session 
     * 
     */ 
    public function destroy () { 
        if (true === $this -> bIsStarted) { 
            session_destroy (); 
            $this -> bIsStarted = false; 
        } 
    } 
 
    /** 
     * Destroy totally current session (session, globals, cookie) 
     * 
     */ 
    public function destroyAll () { 
        $this -> clear (); 
        if (isset($_COOKIE[session_name()])) { 
           setcookie(session_name(), '', time()-42000, '/'); 
        } 
        session_destroy (); 
        $this -> bIsStarted = false; 
    } 
 
    /** 
     * Get session name 
     * 
     * @return string 
     */ 
    public function getName () { 
        if (true === $this -> bIsStarted) { 
            return session_name (); 
        } 
        return null; 
    } 
 
    /** 
     * Set session name 
     * 
     * @param string $sName 
     * @return string 
     */ 
    public function setName ($sName) { 
        if (true === $this -> bIsStarted) { 
            if (!ctype_alnum ($sName)) { 
                throw new oSessionException (str_replace ('{__NAME__}', $sName, oSessionException::NAME_NOT_ALPHANUMERIC)); 
            } 
            return session_name ($sName); 
        } 
        return null; 
    } 
 
    /** 
     * Returns an array with the session 
     * 
     * @return array 
     */ 
    public function asArray () { 
        if (true === $this -> bIsStarted) { 
            return $_SESSION; 
        } else { 
            return null; 
        } 
    } 
 
    /** 
     * Gets the session keys 
     * 
     * @return array 
     */ 
    public function getKeys () { 
        if (true === $this -> bIsStarted) { 
            return array_keys ($_SESSION); 
        } else { 
            return null; 
        } 
    } 
 
    /** 
     * Clear the current session keys and values 
     * 
     */ 
    public function clear () { 
        foreach (array_keys ($_SESSION) as $mKey) { 
            unset ($_SESSION[$mKey]); 
        } 
    } 
 
    /** 
     * Get session ID 
     * 
     * @return string 
     */ 
    public function getId () { 
        if (true === $this -> bIsStarted) { 
            return session_id (); 
        } 
        return null; 
    } 
 
    /** 
     * Close a session 
     * 
     */ 
    public function close () { 
        if (true === $this -> bIsStarted) { 
            session_write_close (); 
        } 
    } 
} 
 
/** 
 * Testing 
 */ 
ob_start (); 
try { 
    $oSession = new oSession ('config.xml'); 
    $oSession -> open (); 
    $oSession['ID'] = 666; 
    echo $oSession['ID']; 
    echo '<br />'; 
    echo $oSession -> getId (); 
    echo '<br />'; 
    $oSession -> destroy (); 
    echo count ($oSession); 
    foreach ($oSession as $sKey => $mVal) { 
        echo $sKey, ' => ', $mVal, '<br />'; 
    } 
    $oSession -> open (); 
    $oSession['NAME'] = 'test'; 
    echo '<br />'; 
    echo count ($oSession); 
    echo '<br />'; 
    foreach ($oSession as $sKey => $mVal) { 
        echo $sKey, ' => ', $mVal, '<br />'; 
    } 
    echo $oSession -> getName (); 
    echo '<br />'; 
    echo $oSession -> getId (); 
    echo '<br />'; 
    $oSession -> setName (1245.5); 
} catch (Exception $e) { 
    echo $e -> getMessage (); 
} 
 
ob_end_flush (); 
?>
 
 |