Location: PHPKode > scripts > PHPStopFlood > phpstopflood/Container/PEAR_MDB2.php
<?php

/**
 * PHPStopFlood_Container_MDB2 class definition
 * @package Containers
 * 
 */

require_once dirname(__FILE__) . '/../Container.php';

/**
 * PEAR::MDB2 container class. This class stores PHPStopFlood data in database using 
 * PEAR::MDB2 class to access this data. 
 * 
 * To use this container you need to have {@link http://pear.php.net/package/MDB2 PEAR::MDB2 package} 
 * installed 
 * 
 * Container supports the following options:
 * - <b>db_object</b> - Required. PEAR::MDB2 class instance to access database
 * - <b>table</b> - Required. String. Table name where to store data
 * Create the following table to store counter logs:
 * <pre>
 * CREATE TABLE `fc_logs` (
 *		//Replace 32 below with the maximum length of UniqueId you will use
 *      `unique_id` varchar(32) NOT NULL
 *      `data` text NOT NULL,
 *      `access` int UNSIGNED NOT NULL,
 *      PRIMARY KEY (`unique_id`)
 * );
 * </pre>
 * - <b>autooptimize</b> - Optional. Boolean. Defaults to False. If True - database table 
 * optimization will be executed at the end of each garbage collection cycle. This operation 
 * improves read/write performance but takes much time to execute so please ensure you have issued 
 * {@link PHPStopFlood::setProbability} with small enough value like 0.1 for example before using this
 * option. Otherwise hackers may DoS your database server.
 * 
 *
 * @package  PHPStopFlood
 * @subpackage Containers
 * @author   Vladislav Rastrusny <hide@address.com>
 * @license  http://www.gnu.org/licenses/lgpl.html  GNU Lesser General Public License
 * @link     http://pear.php.net/package/PHPStopFlood
 */

class PHPStopFlood_Container_PEAR_MDB2 extends PHPStopFlood_Container {

	/**
	 * Database object instance
	 *
	 * @internal 
	 * @var    object
	 */
	protected $_db = null;

	/**
	 * @internal
	 * @see PHPStopFlood_Container::_setDefaults()
	 */
	protected function _setDefaults() {
		$this->_options ['db_object'] = '';
		$this->_options ['table'] = 'fc_logs';
		$this->_options ['autooptimize'] = false;
	}

	/**
	 * @internal
	 * @see PHPStopFlood_Container::set()
	 */
	protected function _initialize() {
		if (! ($this->_options ['db_object'] instanceof MDB2_Driver_Common)) {
			throw new PHPStopFlood_Exception('PEAR::MDB2 database object is not set!');
		}
		$this->_db = $this->_options ['db_object'];
		
		if (PEAR::isError($this->_db)) {
			throw new PHPStopFlood_Exception($this->_db->getMessage(), $this->_db->getCode());
		}
	
	}

	/**
	 * @internal
	 * @see PHPStopFlood_Container::read()
	 */
	public function read($uniqueId) {
		$query = sprintf("SELECT data FROM %s WHERE unique_id = %s", 
			$this->_db->quoteIdentifier($this->_options ['table']), 
			$this->_db->quote($uniqueId, 'text'));
		$result = $this->_db->queryOne($query);
		if (PEAR::isError($result)) {
			throw new PHPStopFlood_Exception($result->getMessage(), $result->getCode());
		}
		if (is_null($result)) {
			return array();
		} else {
			return @unserialize($result);
		}
	}

	/**
	 * @internal
	 * @see PHPStopFlood_Container::write()
	 */
	public function write($uniqueId, array $data) {
		$quotedTblName = $this->_db->quoteIdentifier($this->_options ['table']);
		$this->_db->beginTransaction();
		$query = sprintf("DELETE FROM %s WHERE unique_id = %s", $quotedTblName, 
			$this->_db->quote($uniqueId, 'text'));
		$result = $this->_db->exec($query);
		if (PEAR::isError($result)) {
			throw new PHPStopFlood_Exception($result->getMessage(), $result->getCode());
		}
		$query = sprintf("INSERT INTO %s (unique_id, data, access) VALUES (%s, %s, %d)", 
			$quotedTblName, $this->_db->quote($uniqueId, 'text'), 
			$this->_db->quote(serialize($data), 'text'), time());
		$result = $this->_db->exec($query);
		if (PEAR::isError($result)) {
			$this->_db->rollback();
			throw new PHPStopFlood_Exception($result->getMessage(), $result->getCode());
		}
		$this->_db->commit();
	}

	/**
	 * @internal
	 * @see PHPStopFlood_Container::gc()
	 */
	public function gc($lifetime) {
		$quotedTblName = $this->_db->quoteIdentifier($this->_options ['table']);
		$query = sprintf("DELETE FROM %s WHERE access < %d", $quotedTblName, time() - $lifetime);
		$result = $this->_db->exec($query);
		if (PEAR::isError($result)) {
			throw new PHPStopFlood_Exception($result->getMessage(), $result->getCode());
		}
		if ($this->_options ['autooptimize']) {
			switch ( $this->_db->phptype) {
				case 'mysql' :
					$query = sprintf("OPTIMIZE TABLE %s", $quotedTblName);
				break;
				case 'pgsql' :
					$query = sprintf("VACUUM %s", $quotedTblName);
				break;
				default :
					$query = null;
				break;
			}
			if (! is_null($query)) {
				$result = $this->_db->exec($query);
				if (PEAR::isError($result)) {
					throw new PHPStopFlood_Exception($result->getMessage(), $result->getCode());
				}
			}
		}
	}
}

?>
Return current item: PHPStopFlood