PHP: Session stored in database not always updated
When storing sessions in a database, I have noticed that updating a session does not necessarily invoke the write function that was set in session_set_save_handler(). This problem seems to be solved when you call session_write_close() at the end of the script.

Am I missing something or is this indeed what needs to be done when storing sessions in a database using session_set_save_handler()?

The code that I am currently using.

    // EXECUTE AT START OF SCRIPT
    $session = new Session();
    session_start();

Session Class

	public function __construct() {
		$database		= Database::instance();
		$this->dbh		= $database->dbh();
		$this->lifetime	= get_cfg_var('session.gc_maxlifetime');
		
		session_set_save_handler(
			array(&$this, 'open'),
			array(&$this, 'close'),
			array(&$this, 'read'),
			array(&$this, 'write'),
			array(&$this, 'destroy'),
			array(&$this, 'clean')
		);
	}
	
	// SESSION HANDLER METHODS
	function open($savePath, $sessionName) {
		return true;
	}
	
	function close() {
		return true;
	}
	
	function read($sessionUuid) {
		logMessage('READ SESSION DATA > ' . $sessionUuid);
		$data = array();
		$time = time();
		
		$sth = $this->dbh->prepare("SELECT sessionData FROM phpSession WHERE sessionUuid = :sessionUuid AND expires > " . $time);
		$sth->setFetchMode(PDO::FETCH_ASSOC);
		
		try {
			$sth->execute(array('sessionUuid' => $sessionUuid));
			
			if ($sth->rowCount() == 1) {
				$row = $sth->fetch();
				$data = $row['sessionData'];
			}
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return $data;
	}
	
	function write($sessionUuid, $sessionData) {
		logMessage('WRITE SESSION DATA > ' . $sessionUuid);
		$time = time() + $this->lifetime;
		
		$sth1 = $this->dbh->prepare("SELECT sessionUuid FROM phpSession WHERE sessionUuid = :sessionUuid");
		
		try {
			$sth1->execute(array('sessionUuid' => $sessionUuid));
			
			$query	= '';
			$data	= array(
				'sessionUuid'	=> $sessionUuid,
				'sessionData'	=> $sessionData,
				'expires'		=> $time
			);
			
			if ($sth1->rowCount() == 1) {
				// UPDATE
				$query = "UPDATE phpSession SET sessionUuid = :sessionUuid, sessionData = :sessionData, expires = :expires";
				
			} else {
				// INSERT
				$query = "INSERT INTO phpSession (sessionUuid, sessionData, expires) VALUES (:sessionUuid, :sessionData, :expires)";
			}
			
			$sth2 = $this->dbh->prepare($query);
			
			try {
				$sth2->execute($data);
				
			} catch (PDOException $exception) {
				// HANDLE EXCEPTION
			}
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return true;
	}
	
	function destroy($sessionUuid) {
		$sth = $this->dbh->prepare("DELETE FROM phpSession WHERE 'sessionUuid' = :sessionUuid");
		
		try {
			$sth->execute(array('sessionUuid' => $sessionUuid));
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return true;
	}
	
	function clean() {
		$sth = $this->dbh->prepare("DELETE FROM phpSession WHERE 'expires' < UNIX_TIMESTAMP()");
		
		try {
			$sth->execute();
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return true;
	}


PHP: Session stored in database not always updated
===

When storing sessions in a database, I have noticed that updating a session does not necessarily invoke the write function that was set in session_set_save_handler(). This problem seems to be solved when you call session_write_close() at the end of the script.

Am I missing something or is this indeed what needs to be done when storing sessions in a database using session_set_save_handler()?

The code that I am currently using.

    // EXECUTE AT START OF SCRIPT
    $session = new Session();
    session_start();

Session Class

	public function __construct() {
		$database		= Database::instance();
		$this->dbh		= $database->dbh();
		$this->lifetime	= get_cfg_var('session.gc_maxlifetime');
		
		session_set_save_handler(
			array(&$this, 'open'),
			array(&$this, 'close'),
			array(&$this, 'read'),
			array(&$this, 'write'),
			array(&$this, 'destroy'),
			array(&$this, 'clean')
		);
	}
	
	// SESSION HANDLER METHODS
	function open($savePath, $sessionName) {
		return true;
	}
	
	function close() {
		return true;
	}
	
	function read($sessionUuid) {
		logMessage('READ SESSION DATA > ' . $sessionUuid);
		$data = array();
		$time = time();
		
		$sth = $this->dbh->prepare("SELECT sessionData FROM phpSession WHERE sessionUuid = :sessionUuid AND expires > " . $time);
		$sth->setFetchMode(PDO::FETCH_ASSOC);
		
		try {
			$sth->execute(array('sessionUuid' => $sessionUuid));
			
			if ($sth->rowCount() == 1) {
				$row = $sth->fetch();
				$data = $row['sessionData'];
			}
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return $data;
	}
	
	function write($sessionUuid, $sessionData) {
		logMessage('WRITE SESSION DATA > ' . $sessionUuid);
		$time = time() + $this->lifetime;
		
		$sth1 = $this->dbh->prepare("SELECT sessionUuid FROM phpSession WHERE sessionUuid = :sessionUuid");
		
		try {
			$sth1->execute(array('sessionUuid' => $sessionUuid));
			
			$query	= '';
			$data	= array(
				'sessionUuid'	=> $sessionUuid,
				'sessionData'	=> $sessionData,
				'expires'		=> $time
			);
			
			if ($sth1->rowCount() == 1) {
				// UPDATE
				$query = "UPDATE phpSession SET sessionUuid = :sessionUuid, sessionData = :sessionData, expires = :expires";
				
			} else {
				// INSERT
				$query = "INSERT INTO phpSession (sessionUuid, sessionData, expires) VALUES (:sessionUuid, :sessionData, :expires)";
			}
			
			$sth2 = $this->dbh->prepare($query);
			
			try {
				$sth2->execute($data);
				
			} catch (PDOException $exception) {
				// HANDLE EXCEPTION
			}
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return true;
	}
	
	function destroy($sessionUuid) {
		$sth = $this->dbh->prepare("DELETE FROM phpSession WHERE 'sessionUuid' = :sessionUuid");
		
		try {
			$sth->execute(array('sessionUuid' => $sessionUuid));
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return true;
	}
	
	function clean() {
		$sth = $this->dbh->prepare("DELETE FROM phpSession WHERE 'expires' < UNIX_TIMESTAMP()");
		
		try {
			$sth->execute();
			
		} catch (PDOException $exception) {
			// HANDLE EXCEPTION
		}
		
		return true;
	}

