www.webdeveloper.com
Results 1 to 2 of 2

Thread: Custom session woes

  1. #1
    Join Date
    Aug 2007
    Location
    London
    Posts
    410

    Question Custom session woes

    Hello all,

    I've been trying to implement custom session management. It causes problems, however, and I'm sure it's hideously inefficient and ugly... I'm not sure what to do to it, to improve it. Any suggestions would be grand (it overloads the memory for starters).
    (removed some docs to stay within char count)

    PHP Code:
    /**
     * Handles Session data.
     *
     * @class Session
     * @package framework:core
     * @file Session.php
     * @extends RequestDataObject
     * @single
     * @final
    */

    final class Session extends RequestDataObject {
        private 
    $connector;
        private 
    $file;
        private 
    $id;
        
        public function 
    __construct() {
            switch(
    Config::read("session.security")) {
                case 
    "high":
                    
    Config::write("session.cookie_lifetime"0);
                    break;
                case 
    "medium":
                    
    Config::write("session.cookie_lifetime"7*86400);
                    break;
                case 
    "low":
                default:
                    
    Config::write("session.cookie_lifetime"24*7*86400);
                    break;
            }
            if(
    Config::read("session.management") == "database") {
                
    $database = (is_null(Config::read("session.database"))) ? "default" Config::read("session.database");
            }
            
    Session::start();
        }
        
        
    /**
         * Returns a singleton instance of the Session class.
         * 
         * @method &getInstance
         * @access private
         * @returns Session singleton instance of the Session class.
        */
        
        
    private function &getInstance() {
            static 
    $instance = array();
            if(!
    $instance) {
                
    $instance[0] =& new Session();
            }
            return 
    $instance[0];
        }
        
        
    /**
         * Starts the session
         * 
         * @method start
         * @access public
         * @returns void
        */
        
        
    public function start() {
            
    $_this =& Session::getInstance();
            if(!
    is_null(Cookie::get("session_id")) && $_this->_checkSessionValidity(Cookie::get("session_id"))) {
                
    $_this->id Cookie::get("session_id");
            } else {
                
    $_this->destroy();
                
    $_this->id Security::uniqueId($_SERVER["REMOTE_ADDR"]);
                
    Cookie::set("session_id"$_this->idConfig::read("session.cookie_lifetime"));
            }
            
    $this->Connector = new Connector($database);
            
    $_this->file Config::read("dir.site") . "/protected/sessions/{$_this->id}.session";
            switch(
    Config::read("session.management")) {
                case 
    "database":
                    
    $_this->_startSessionDatabase();
                    break;
                case 
    "file":
                default:
                    
    $_this->_startSessionFile();
                    break;
            }        
                
        }
        
        
    /**
         * Starts a session using the database method.
         * 
         * @method _startSessionDatabase
         * @access protected
         * @returns void
        */
        
        
    private function _startSessionDatabase() {
            
    $_this =& Session::getInstance();
            if(
    mysql_num_rows($_this->connector->query("SELECT * FROM sessions WHERE 'session_id' = '{$_this->id}';")) != 1) { 
                
    $_this->connector->query("INSERT INTO sessions (session_id, expires, data) VALUES ('{$_this->id}', '" . (time() + Config::read("session.cookie_lifetime")) . "', '');");
            } else {
                
    $_this->_cacheDatabase();
            }
        }
        
        
    /**
         * Starts a session using the file method.
         * 
         * @method _startSessionFile
         * @access private
         * @returns void
        */
        
        
    private function _startSessionFile() {
            
    $_this =& Session::getInstance();
            if(!
    file_exists(INCL_PATH $_this->file)) {
                
    Filesystem::writeToFile($_this->file"expires:::" . (time() + Config::read("session.cookie_lifetime")) . ";;;");
            } else {
                
    $_this->_cacheFile();
            }
        }
        
        
    /**
         * Destroys the specified session (or current session if parameter is null).
         * 
         * @method destroy
         * @access public
         * @param string $session_id
         * @returns void
        */
        
        
    public function destroy($session_id null) {
            
    $_this Session::getInstance();
            if(
    is_null($session_id)) $session_id $_this->id;
            
    $_this->_destroyDatabaseSession($session_id);
            
    $_this->_destroyFileSession($session_id);
        }
        
        
    /**
         * Destroys a session using the database method.
         * 
         * @method _destroyDatabaseSession
         * @access private
         * @param string $session_id
         * @returns void
        */
        
        
    private function _destroyDatabaseSession($session_id) {
            
    $_this =& Session::getInstance();
            if(
    $_this->id != Cookie::get("session_id") && mysql_num_rows($_this->connector->query("SELECT * FROM sessions WHERE session_id = '{Cookie::get('session_id')}';")) > 0) {
                
    $_this->connector->query("UPDATE sessions SET valid = false WHERE session_id = '{Cookie::get('session_id')}';");
            }
            if(
    mysql_num_rows($_this->connector->query("SELECT * FROM sessions WHERE session_id = '{$_this->id}';")) > 0) {
                
    $_this->connector->query("UPDATE sessions SET valid = false WHERE session_id = '{$_this->id}';");
            }
        }
        
        
    /**
         * Destroys a session using the file method.
         * 
         * @method _destroyFileSession
         * @access private
         * @param string $session_id
         * @returns void
        */
        
        
    private function _destroyFileSession($session_id) {
            
    $_this =& Session::getInstance();
            if(
    file_exists(INCL_PATH $_this->file)) {
                
    unlink(INCL_PATH $_this->file);
            }
        }
        
        
    /**
         * Sets a session variable.
         * 
         * @method set
         * @access public
         * @param string $name
         * @param string $value
         * @returns boolean success
        */
        
        
    public function set($name$value) {
            
    $_this =& Session::getInstance();
            if(
    $name == "expires") return false;
            switch(
    Config::read("session.management")) {
                case 
    "database":
                    return 
    $_this->_setDatabase($name$value);
                    break;
                case 
    "file":
                default:
                    return 
    $_this->_setFile($name$value);
                    break;
            }
        }
        
        
    /**
         * Sets a session variable in the database.
         * 
         * @method _setDatabase
         * @access private
         * @param string $name
         * @param string $value
         * @returns boolean success
        */
        
        
    private function _setDatabase($name$value) {
            
    $_this =& Session::getInstance();
            
    $value str_replace(array(":::"";;;"), ""$value);
            
    Cleaner::clean($name);
            
    Cleaner::clean($value);
            
    Cleaner::sql($value);
            
    parent::delete($name);
            
    $data_string $_this->_compileDataAsString();
            if(
    substr($data_string, -3) != ";;;") {
                
    $data_string .= ";;;";
            }
            
    $data_string .= "$name:::$value";
            if(
    $_this->connector->query("UPDATE sessions SET data = \"$data_string\" WHERE session_id = \"{$_this->id}\";")) {
                
    parent::set($name$value);
                return 
    true;
            } else {
                return 
    false;
            }
        }
        
        
    /**
         * Sets a session variable in the file.
         * 
         * @method _setFile
         * @access private
         * @param string $name
         * @param string $value
         * @returns boolean success
        */
        
        
    private function _setFile($name$value) {
            
    $_this =& Session::getInstance();
            
    $value str_replace(array(":::"";;;"), ""$value);
            
    Cleaner::clean($value);
            
    Cleaner::clean($name);
            
    parent::delete($name);
            
    $data_string $_this->_compileDataAsString();
            if(
    file_exists($_this->file)) {
                
    Filesystem::writeToFile($_this->file"$name:::$file;;;"true);
                
    parent::set($name$value);
                return 
    true;
            } else {
                return 
    false;
            }
        }
        
        
    /**
         * Caches the session using the database.
         * 
         * @method _cacheDatabase
         * @access private
         * @returns void
        */
        
        
    private function _cacheDatabase() {
            
    $_this =& Session::getInstance();
            
    $sesh mysql_fetch_array($_this->connector->query("SELECT * FROM sessions WHERE session_id = '{$_this->id}';"));
            foreach(
    parseString($sesh["data"], ":::"";;;") as $k=>$v) {
                
    parent::set($k$v);
            }
        }
        
        
    /**
         * Caches the session using the file.
         * 
         * @method _cacheFile
         * @access private
         * @returns void
        */
        
        
    private function _cacheFile() {
            
    $_this =& Session::getInstance();
            
    $data Filesystem::parseFile($_this->file":::"";;;");
            foreach(
    $data as $k => $v) {
                
    parent::set($k$v);
            }
        }
        
        
    /**
         * Checks the validity of a session.
         * 
         * @method _checkSessionValidity
         * @access private
         * @param string $session_id
         * @returns boolean session is valid
        */
        
        
    private function _checkSessionValidity($session_id null) {
            
    $_this =& Session::getInstance();
            if(
    is_null($session_id) && !is_null($_this->getId())) {
                
    $session_id $_this->getId();
            } elseif (
    is_null($session_id) && is_null($_this->getId())) {
                return 
    false;
            }
            switch(
    Config::read("session.management")) {
                case 
    "database":
                    
    $sessionResult $_this->connector->query("SELECT * FROM sessions WHERE 'session_id' = '$session_id' AND valid = true AND expires > " time() . ";");
                    if(
    mysql_num_rows($sessionResult) == 1) {
                        return 
    true;
                    }
                    return 
    false;
                    break;
                case 
    "file":
                default:
                    
    $vars Filesystem::parseFile($_this->file":::"";;;");
                    if(isset(
    $var["expires"]) && intval($var["expires"]) > time()) {
                        unset(
    $vars);
                        return 
    true;
                    } else {
                        unset(
    $vars);
                        return 
    false;
                    }
                    break;
            }
        }
        
        
    /**
         * Cleans up old sessions.
         * 
         * @method housekeeping
         * @access public
         * @returns void
        */
        
        
    public function housekeeping() {
            
    $_this =& Session::getInstance();
            
    $_this->_cleanDatabase();
            
    $_this->cleanFiles();
        }
        
        
    /**
         * Cleans up session database.
         *
         * @method _cleanDatabase
         * @access private
         * @returns void
        */
        
        
    private function _cleanDatabase() {
            
    $_this->connector->query("DELETE * FROM sessions WHERE expires < " time() + " OR valid = false;");
        }
        
        
    /**
         * Cleans up session files.
         * 
         * @method _cleanFiles
         * @access private
         * @returns void
        */
        
        
    private function _cleanFiles() {
            
    $files Filesystem::scanDirectory(Config::read("dir.site") . "/protected/sessions/""extension:session");
            foreach(
    $files as $file) {
                
    $vars Filesystem::parseFile($file":::"";;;");
                if(
    $vars["expires"] <= time()) {
                    
    unlink(INCL_PATH $file);
                }
                unset(
    $vars);
            }
        }
        
        
    /**
         * Gets the session id.
         * 
         * @method getId
         * @access public
         * @returns string session id
        */
        
        
    public function getId() {
            
    $_this =& Session::getInstance();
            return 
    $_this->id;
        }
        


  2. #2
    Join Date
    Aug 2007
    Location
    London
    Posts
    410

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles