branko ajzele, senior developer / project manager

Posts / Articles

Zend_Auth database based identity persistence

Wrote a new article on Inchoo.net, you can read it here. Basically, I wrote a storage class for those of you who dislike using default Zend_Auth session storage.

You can see the class code below. For any extra info, please visit the Inchoo.net article (direct link) or visit the ZF Snippets site (direct link).

<?php
 
class AuthDbStorage implements Zend_Auth_Storage_Interface
{
	private static $_session = 'session';
 
	private static $_requiredFieldUserId = 'uid';
	private static $_requiredFieldSessionId = 'sid';
	private static $_requiredFieldHostname = 'hostname';
	private static $_requiredFieldAccessed = 'accessed';
	// Extra field to store some info (use serialize)
	private static $_requiredFieldExtra = 'extra';
 
 
	// Zend_Auth Adapter fields
	private static $_authAdapterIdentityColumn;
	private static $_authAdapterTableName;
	private static $_timeToExpire = 600;
 
	private static $_cookieName;
 
	private $_db;
 
	public function __construct(Zend_Db_Adapter_Abstract $adapter, $cookieName, $authAdapterTableName, $authAdapterIdentityColumn, $timeToExpire = null)
	{
		$this->_db = $adapter;
		self::$_cookieName = $cookieName;
		self::$_authAdapterTableName = $authAdapterTableName;
		self::$_authAdapterIdentityColumn = $authAdapterIdentityColumn;
		self::$_timeToExpire = $timeToExpire;
	}
 
    /**
     * Returns true if and only if storage is empty
     *
     * @throws Zend_Auth_Storage_Exception If it is impossible to determine whether storage is empty
     * @return boolean
     */
    public function isEmpty()
    {
		$result = $this->_db->fetchRow('SELECT * FROM '.self::$_session.' WHERE '.self::$_requiredFieldSessionId.' = ?',  array($_COOKIE[self::$_cookieName]));
 
		if(empty($result)) { return true; }
    	return false;
    }
 
    /**
     * Returns the contents of storage
     *
     * Behavior is undefined when storage is empty.
     *
     * @throws Zend_Auth_Storage_Exception If reading contents from storage is impossible
     * @return mixed
     */
    public function read()
    {    	
    	$result = $this->_db->fetchRow('SELECT * FROM '.self::$_session.' WHERE '.self::$_requiredFieldSessionId.' = ?', array($_COOKIE[self::$_cookieName]));
 
    	if(time() - $result[self::$_requiredFieldAccessed] > self::$_timeToExpire)
		{
			$this->clear();
			return null;
		}
		//if (is_null($result)) { throw new Zend_Auth_Storage_Exception(); }
		return $result;    	
    }
 
    /**
     * Writes $contents to storage
     *
     * @param  mixed $contents
     * @throws Zend_Auth_Storage_Exception If writing $contents to storage is impossible
     * @return void
     */
    public function write($contents, $extraContents = array())
    {    	
    	if(is_array($contents))
    	{
    		$userId = $contents[self::$_requiredFieldUserId];	
    	}
 
    	else 
    	{
    		$userId = $this->_db->fetchOne('SELECT * FROM '.self::$_authAdapterTableName.' WHERE '.self::$_authAdapterIdentityColumn.' = ?', array($contents));	
    	}
 
		$fields = array(
			self::$_requiredFieldUserId 	=> $userId,
			self::$_requiredFieldSessionId 	=> $_COOKIE[self::$_cookieName],
			self::$_requiredFieldHostname 	=> $_SERVER['REMOTE_ADDR'],
			self::$_requiredFieldAccessed 	=> time()
		);
 
		if(!empty($extraContents))
		{
			$fields[self::$_requiredFieldExtra] = serialize($extraContents); 
		}
 
		// Before write, delete all session info
		$this->clear();
 
		// Check to see if session has expired
 
		// Now write new one
		$result = $this->_db->insert(self::$_session, $fields);
 
    	if($result == 0) { throw new Zend_Auth_Storage_Exception(); }
 
    }
 
    /**
     * Clears contents from storage
     *
     * @throws Zend_Auth_Storage_Exception If clearing contents from storage is impossible
     * @return void
     */
    public function clear()
    {	
		try 
		{
			$this->_db->query('DELETE FROM '.self::$_session.' WHERE '.self::$_requiredFieldSessionId.' = ?', array($_COOKIE[self::$_cookieName]));
		}
		catch (Exception $ex)
		{
			throw new Zend_Auth_Storage_Exception();
		}
    }
}