Mysql.class.php 4.59 KB
<?php
/**
 * [db]
 */

/**
 * 传入options项目结构为
 * [config] = 配置文件名
 * [domain] = 文件存储域
 */
class Util_Server_Adapter_Db_Mysql implements Util_Server_Adapter_Interface {
	const TIMEOUT = 15; //存储Tracker延迟时间
	

	const SECTION = 'mysql'; //配置文件中有关数据库的配置段
	

	private $_config = '';
	private $_readtag = true;
	private $_dbname = '';
	private $_tagname = '';
	
	private $_username = '';
	private $_password = '';
	private $_host = '';
	private $_port = '';
	/**
	 * 创建函数
	 *
	 * @param array $options 配置数组:config
	 */
	public function __construct($options) {
		if (! is_array ( $options ))
			throw new Util_Server_Exception ( get_class ( $this ) . ':必须提供数据库选项!' );
		
		$this->_config = Util_Common_Core::loadDbMysql ();
		
		//得到数据库名称
		if (isset ( $options ['dbname'] ) && $options ['dbname'] != '')
			$this->_tagname = $options ['dbname'];
		else
			throw new Util_Server_Exception ( get_class ( $this ) . ':请您提供标识符名称!' );
			
		//得到数据库操作(读/写)
		if (isset ( $options ['dbname'] ) && is_bool ( $options ['readtag'] ))
			$this->_readtag = $options ['readtag'];
		else
			throw new Util_Server_Exception ( get_class ( $this ) . ':请您提供读写标志!' );
	}
	
	public function __destruct() {
	}
	
	/**
	 * 得到可用文件服务器的配置host, port列表
	 * 使用:$mem = new Memcache();$mem->addServer(host, port)方式生成对象。
	 *
	 * @return array or false
	 */
	public function loadBalanceServer() {
		$servers = $this->loadServers ();
		if (empty ( $servers ))
			return false;
		
		$return = $this->_getValidServer ( $servers );
		if ($return === false)
			return false;
		$return ['dbname'] = $this->_dbname;
		$return ['username'] = $this->_username;
		$return ['password'] = $this->_password;
		return $return;
	}
	
	/**
	 * 得到有效的服务器,通过fsocket检测IP和端口
	 *
	 * @param array $servers
	 * @return array|false
	 */
	private function _getValidServer($servers) {
		$counter = count ( $servers );
        if (($rdm = rand ( 1, $counter )) && Util_Server_Adapter_CheckServer::check( $servers [$rdm - 1] ['host'], $servers [$rdm - 1] ['port']) === true )
			return $servers [$rdm - 1];
		elseif (($rdm = rand ( 1, $counter )) && Util_Server_Adapter_CheckServer::check( $servers [$rdm - 1] ['host'], $servers [$rdm - 1] ['port'] ) === true )
			return $servers [$rdm - 1];
		else
			return false;
	}
	
	/**
	 * 读取数据库服务器列表,配置中格式:定义再[mysql]段,格式为:192.168.4.133:3306,192.168.4.134:3306
	 *
	 * @param string $filename
	 * @return array
	 */
	public function loadServers() {
		$svrobj = Util_Common_Core::loadConfig ( $this->_config, self::SECTION );
		$this->_username = str_replace ( ' ', '', $svrobj->{$this->_tagname}->username ); //get username
		$this->_password = str_replace ( ' ', '', $svrobj->{$this->_tagname}->password ); //get password
		$this->_dbname = isset ( $svrobj->{$this->_tagname}->dbname ) ? $svrobj->{$this->_tagname}->dbname : $this->_tagname; //存在dbname项目是,使用该项目,不存在时使用tagname
		

		if ($this->_readtag) {
			$sReader = str_replace ( ' ', '', $svrobj->{$this->_tagname}->readers );
			if ($sReader == '')
				throw new Util_Server_Exception ( get_class ( $this ) . ":在配置文件中没有找到($this->_tagname)标识符!" );
			return $this->_getServersFromString ( $sReader );
		} else {
			$sWriter = str_replace ( ' ', '', $svrobj->{$this->_tagname}->writers );
			if ($sWriter == '')
				throw new Util_Server_Exception ( get_class ( $this ) . ":在配置文件中没有找到($this->_tagname)标识符!" );
			return $this->_getServersFromString ( $sWriter );
		}
	}
	
	/**
	 * 分析取得的服务器字符串,得到服务器配置数组
	 *
	 * @param string $svrstring
	 * @return array
	 */
	private function _getServersFromString($svrstring) {
		if ($svrstring == '')
			throw new Util_Server_Exception ( get_class ( $this ) . ':服务器配置字符串为空!' );
		$tmpary = explode ( ',', $svrstring );
		if (count ( $tmpary ) == 0)
			throw new Util_Server_Exception ( get_class ( $this ) . ':服务器配置字符串格式错误' );
		$return = array ();
		$counter = count ( $tmpary );
		for($i = 0; $i < $counter; $i ++)
			if (($tmp = parse_url ( $tmpary [$i] )) !== false && $this->_checkSvrAry ( $tmp ))
				$return [] = $tmp;
		return $return;
	}
	
	/**
	 * 测试服务器配置数组是否格式正常
	 *
	 * @param array $ary
	 * @return boolean
	 */
	private function _checkSvrAry(array $ary) {
		return isset ( $ary ['host'] ) && isset ( $ary ['port'] );
	}
}