ZF-552: This is a new approach for the Session Module for Zend and is open for any implementation in the future

Description

Come advantages are: - use PHP native functions like: session_start() and session_destroy(); - use the global $_SESSION;

The plugin is using an SQL table (the example is for a MySQL table)

Code:

CREATE TABLE app_session ( session_id varchar(32) collate latin1_general_ci NOT NULL default '', session_time int(11) NOT NULL default '0', session_start int(11) NOT NULL default '0', session_data text collate latin1_general_ci NOT NULL, session_key varchar(50) collate latin1_general_ci default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

The Session class where factory is located.

php:

/** * Application_Plugins_Session_Exception */ require_once 'Application/Plugins/Session/Exception.php';

/** * Factory for Zend_Db_Handler classes. * * @param string $adapterName Name of the adapter to return: * 'database' -> Application_Plugins_Session_Handler_Database * * @param array $config An array of adapter configuration keys. * * @return Application_Plugins_Session_Handler_Abstract * */ class Application_Plugins_Session { static public function factory($adapterName, $configuration = null) {
if (!is_string($adapterName) or !strlen($adapterName)) {
throw new Application_Plugins_Session_Exception('Adapter name must be specified in a string!'); }
$adapterName = 'Application_Plugins_Session_Handler_'.str_replace(' ','_',ucwords(str_replace('_', ' ', $adapterName)));

    # Load adapter
    Zend::loadClass($adapterName);

    return new $adapterName();
}

}

The abstract class from which all other implementations will be extended (sorry for my english):

php: /** * Abstract class for Zend_Session to help enforce private constructs. * * @category Zend * @package Zend_Session */ abstract class Application_Plugins_Session_Handler_Abstract { /** * This is the first function called by PHP when a session is started * * @param string $strSessionPath * @param string $strSessionName */ public function open($strSessionPath, $strSessionName) {

    }

    /**
     * The close function is the last function called by PHP related to the session.
     * It does not accept any parameters, and returns either TRUE or FALSE.
     */
    public function close()
    {

    }

    /**
     * Retrieve any data that is stored for the session, and return it. It is extremely
     * important always to return a string from this function, even if it's empty.
     */
    public function read()
    {

    }

    /**
     * Write session data
     *
     * @param string $strSessionId
     * @param string $SessionData
     */
    public function write($strSessionId,$SessionData)
    {

    }

    /**
     * Destroy session, delete all data related to the session id
     *
     * @param string $strSessionId
     */
    public function destroy($strSessionId)
    {

    }

    public function gc($strSessionLifeTime)
    {

    }

}

The Database implementation php:

/** * Application_Plugins_Session_Handler_Absstract */ require_once 'Application/Plugins/Session/Handler/Abstract.php';

/** * Application_Plugins_Session_Handler_Exception */ require_once 'Application/Plugins/Session/Handler/Exception.php';

class Application_Plugins_Session_Handler_Database extends Application_Plugins_Session_Handler_Abstract { public function open($strSessionPath, $strSessionName) { return true;
}

    public function close()
    {
            return true;
    }

    protected function _generateId()
    {       
            do {
                    # Generate session ID
                    $strSessionId = md5(uniqid(mt_srand((double) microtime() * 1000000))); 

            } while ($this->_validateId($strSessionId) === false);
    }

    protected function _formatSessionData($SessionData)
    {
            $arrSession = array();
            $arrSession = preg_split("/([a-zA-Z0-9\_]+\|)/",$SessionData,-1,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
            return array_chunk($arrSession,2);                       
    }

    protected function _validateId($strSessionId)
    {
            # Get database connection
            $db = Zend::registry('db');

            # Check is the session ID is unique
            $select = $db->select();
            $select->from('app_session','count(session_id) as session_found');
            $select->where('session_id = ?',$strSessionId);
            $intValue = $db->fetchOne($select->__toString()) ;           
            if($intValue) {
                    return false;
            }
            else {
                    return true;
            }
    }


    public function write($strSessionId,$SessionData)
    {
            # Get database connection
            $db = Zend::registry('db');
            $arrSessionData = $this->_formatSessionData($SessionData);

            # Check if the session id exists
            if($this->_validateId($strSessionId))
            {
                    foreach ($arrSessionData as $arrSessionDataKey => $arrSessionDataValue) {                     
                            # ID of the session doesn't exist, perform insert              
                            $db->insert("app_session",array("session_id"=>$strSessionId,"session_time"=>time(),"session_start"=>time(),"session_data"=>$arrSessionDataValue[1],"session_key"=>$arrSessionDataValue[0]));
                    }
            }
            else
            {
                    # ID of the session exists perform update                     
                    foreach ($arrSessionData as $arrSessionDataKey => $arrSessionDataValue) {                            
                            # ID of the session doesn't exist, perform insert              
                            $intAffected = $db->update("app_session",array("session_time"=>time(),"session_key"=>$arrSessionDataValue[0],"session_data"=>$arrSessionDataValue[1]),"session_id = '".$strSessionId."' and session_key = '".$arrSessionDataValue[0]."'");
                            if(!$intAffected) {
                                    $db->insert("app_session",array("session_id"=>$strSessionId,"session_time"=>time(),"session_start"=>time(),"session_data"=>$arrSessionDataValue[1],"session_key"=>$arrSessionDataValue[0]));                   
                            }
                    }                                          
            }
            return true;
    }

    public function destroy($strSessionId)
    {
            # Get database connection
            $db = Zend::registry('db');

            # Check if the session id exists
            if(!$this->_validateId($strSessionId))
            {
                    # Delete session and data associated with it from database
                    return $db->delete("app_session","session_id= '".$strSessionId."'") > 0 ? true : false;
            }
            return true;
    }

    public function gc($strSessionLifeTime = 30)
    {
            # Get database connection
            $db = Zend::registry('db');

            # Load application configuration parameters to get session lifetime
            $config_app = Zend::registry('config_app');

            $strSessionLifeTime = strtotime("-".$config_app->lifetime." minutes");
            $db->delete("app_session","session_time < ".$strSessionLifeTime);
            return true;
    }

    public function read($strSessionId)
    {
            # Get database connection
            $db = Zend::registry('db');

            # Get all data associated with the session
            $select = $db->select();
            $select->from('app_session',"(GROUP_CONCAT(session_key,session_data SEPARATOR '')) as session_data");
            $select->where('session_id = ?',$strSessionId);
            $SessionData = $db->fetchAll($select->__toString());           


            # If no results the empty string will be returned
            return $SessionData ;
    }

}

Comments

No comments to display