php实现带读写分离功能的MySQL类完整实例
本文实例讲述了php实现带读写分离功能的MySQL类。分享给大家供大家参考,具体如下:
概述:
1.根据sql语句判断是连接读库还是写库
2.链式调用$this->where()->get()
3.不同的主机对应不同的实例,不再多次new
具体代码如下:
<?php classDBRWmysql { privatestatic$Instance=null; private$links=array();//链接数组 private$link=null;//当前连接 public$dbType='read'; public$_host='';//数据库所在主机名 public$_database='';//当前数据库名 public$_tablename='';//当前表的表名 public$_dt='';//database.tablename public$isRelease=0;//查询完成后是否释放 public$fields='*'; public$arrWhere=[]; public$order=''; public$arrOrder=[]; public$limit=''; public$sql=''; public$rs;//结果集 privatefunction__construct($database='',$tablename='',$isRelease=0) { $this->_database=$database;//databasename $this->_tablename=$tablename;//tablename $this->_dt="`{$this->_database}`.`{$this->_tablename}`"; $this->isRelease=$isRelease; } publicstaticfunctiongetInstance($database='',$tablename='',$isRelease=0) { if(self::$Instance==null){ self::$Instance=newDBRWmysql($database,$tablename,$isRelease); } self::$Instance->_database=$database; self::$Instance->_tablename=$tablename; self::$Instance->_dt="`{$database}`.`{$tablename}`"; self::$Instance->isRelease=$isRelease; returnself::$Instance; } //如果主机没变,并且已经存在MYSQL连接,就不再创建新的连接 //如果主机改变,就再生成一个实例创建一个连接 //type=='write'或'read' publicfunctiongetLink($type) { $this->dbType=$$type; //随机选取一个数据库连接(区分读写) $dbConfig=DBConfig::$$type; $randKey=array_rand($dbConfig); $config=$dbConfig[$randKey]; //链接数据库 $host=$config['host']; $username=$config['username']; $password=$config['password']; if(empty($this->links[$host])){ $this->_host=$host; $this->links[$host]=newmysqli($host,$username,$password); if($this->links[$host]->connect_error){ $this->error($this->links[$host]->connect_error); } } //初始化链接 $this->link=$this->links[$host]; $this->link->query("setnamesutf8mb4;");//支持emoji表情 $this->link->query("use{$this->_database};"); } publicfunctiongetCurrentLinks() { return$this->links; } //析构函数 publicfunction__destruct() { foreach($this->linksas$v){ $v->close(); } } //查询封装 publicfunctionquery($sql) { $this->sql=$sql; if(strpos($sql,'select')!==false){ $this->getLink('read');//读库 }else{ $this->getLink('write');//写库 } $this->rs=$this->link->query($sql); ($this->rs===false)&&$this->error('sqlerror:'.$sql.PHP_EOL.$this->link->error); //查询完成后释放链接,并删除链接对象 if($this->isRelease){ $this->link->close(); unset($this->links[$this->_host]); } return$this->rs; } //增 publicfunctioninsert($arrData) { foreach($arrDataas$key=>$value){ $fields[]=$key; $values[]="'".$value."'"; //$fields[]='`'.$key.'`'; //$values[]="'".$value."'"; } $strFields=implode(',',$fields); $strValues=implode(',',$values); $sql="insertinto{$this->_dt}($strFields)values($strValues)"; $this->query($sql); $insert_id=$this->link->insert_id; return$insert_id; } //增 publicfunctionreplace($arrData) { foreach($arrDataas$key=>$value){ $fields[]=$key; $values[]="'{$value}'"; } $strFields=implode(',',$fields); $strValues=implode(',',$values); $sql="replaceinto{$this->_dt}($strFields)values($strValues)"; $this->query($sql); return$this->link->insert_id; } //增 //每次插入多条记录 //每条记录的字段相同,但是值不一样 publicfunctioninsertm($arrFields,$arrData) { foreach($arrFieldsas$v){ //$fields[]="`{$v}`"; $fields[]=$v; } foreach($arrDataas$v){ $data[]='('.implode(',',$v).')'; } $strFields=implode(',',$fields); $strData=implode(',',$data); $sql="insertinto{$this->_dt}($strFields)values{$strData}"; $this->query($sql); return$this->link->insert_id; } //删 publicfunctiondelete() { $where=$this->getWhere(); $limit=$this->getLimit(); $sql="deletefrom{$this->_dt}{$where}{$limit}"; $this->query($sql); return$this->link->affected_rows; } //改 publicfunctionupdate($data) { $where=$this->getWhere(); $arrSql=array(); foreach($dataas$key=>$value){ $arrSql[]="{$key}='{$value}'"; } $strSql=implode(',',$arrSql); $sql="update{$this->_dt}set{$strSql}{$where}{$this->limit}"; $this->query($sql); return$this->link->affected_rows; } //获取总数 publicfunctiongetCount() { $where=$this->getWhere(); $sql="selectcount(1)asnfrom{$this->_dt}{$where}"; $resault=$this->query($sql); ($resault===false)&&$this->error('getCounterror:'.$sql); $arrRs=$this->rsToArray($resault); $num=array_shift($arrRs); return$num['n']; } //将结果集转换成数组返回 //如果field不为空,则返回的数组以$field为键重新索引 publicfunctionrsToArray($field='') { $arrRs=$this->rs->fetch_all(MYSQLI_ASSOC);//该函数只能用于php的mysqlnd驱动 $this->rs->free();//释放结果集 if($field){ $arrResult=[]; foreach($arrRsas$v){ $arrResult[$v[$field]]=$v; } return$arrResult; } return$arrRs; } //给字段名加上反引号 publicfunctionqw($strFields) { $strFields=preg_replace('#\s+#','',$strFields); $arrNewFields=explode('',$strFields); $arrNewFields=array_filter($arrNewFields); foreach($arrNewFieldsas$k=>$v){ $arrNewFields[$k]='`'.$v.'`'; } returnimplode(',',$arrNewFields); } //处理入库数据,将字符串格式的数据转换为...格式(未实现) publicfunctiongetInsertData($strData) { //$bmap="jingdu,$jingduweidu,$weiducontent,$content"; } //selectin //arrData整数数组,最好是整数 publicfunctionselect_in($key,$arrData,$fields='') { $fields=$fields?$fields:'*'; sort($arrData); $len=count($arrData); $cur=0; $pre=$arrData[0]; $new=array('0'=>array($arrData[0])); for($i=1;$i<$len;$i++){ if(($arrData[$i]-$pre)==1){ $new[$cur][]=$arrData[$i]; }else{ $cur=$i; $new[$cur][]=$arrData[$i]; } $pre=$arrData[$i]; } $arrSql=array(); foreach($newas$v){ $len=count($v)-1; if($len){ $s=$v[0]; $e=end($v); $sql="(select$fieldsfrom{$this->_dt}where$keybetween$sand$e)"; }else{ $s=$v[0]; $sql="(select$fieldsfrom{$this->_dt}where$key=$s)"; } $arrSql[]=$sql; } $strUnion=implode('UNIONALL',$arrSql); $res=$this->query($strUnion); return$this->rstoarray($res); } //wherein publicfunctionsetWhereIn($key,$arrData) { if(empty($arrData)){ $str="(`{$key}`in('0'))"; $this->addWhere($str); return$str; } foreach($arrDataas&$v){ $v="'{$v}'"; } $str=implode(',',$arrData); $str="(`{$key}`in({$str}))"; $this->addWhere($str); return$this; } //wherein publicfunctionsetWhere($arrData) { if(empty($arrData)){ return''; } foreach($arrDataas$k=>$v){ $str="(`{$k}`='{$v}')"; $this->addWhere($str); } return$this; } //betweenand publicfunctionsetWhereBetween($key,$min,$max) { $str="(`{$key}`between'{$min}'and'{$max}')"; $this->addWhere($str); return$this; } //wherea>b publicfunctionsetWhereBT($key,$value) { $str="(`{$key}`>'{$value}')"; $this->addWhere($str); return$this; } //wherea<b publicfunctionsetWhereLT($key,$value) { $str="(`{$key}`<'{$value}')"; $this->addWhere($str); return$this; } //组装where条件 publicfunctionaddWhere($where) { $this->arrWhere[]=$where; } //获取最终查询用的where条件 publicfunctiongetWhere() { if(empty($this->arrWhere)){ return'where1'; }else{ return'where'.implode('and',$this->arrWhere); } } //以逗号隔开 publicfunctionsetFields($fields) { $this->fields=$fields; return$this; } //orderbyadesc publicfunctionsetOrder($order) { $this->arrOrder[]=$order; return$this; } //获取order语句 publicfunctiongetOrder() { if(empty($this->arrOrder)){ return''; }else{ $str=implode(',',$this->arrOrder); $this->order="orderby{$str}"; } return$this->order; } //e.g.'0,10' //用limit的时候可以加where条件优化:select...whereid>1234limit0,10 publicfunctionsetLimit($limit) { $this->limit='limit'.$limit; return$this; } //直接查询sql语句,返回数组格式 publicfunctionarrQuery($sql,$field='') { $this->query($sql); $this->clearQuery(); ($this->rs===false)&&$this->error('selecterror:'.$sql); return$this->rsToArray($field); } //如果$field不为空,则返回的结果以该字段的值为索引 //暂不支持join publicfunctionget($field='') { $where=$this->getWhere(); $order=$this->getOrder(); $sql="select{$this->fields}from{$this->_dt}{$where}{$order}{$this->limit}"; return$this->arrQuery($sql,$field); } //获取一条记录 publicfunctiongetOne() { $this->setLimit(1); $rs=$this->get(); return!empty($rs)?$rs[0]:[]; } //获取一条记录的某一个字段的值 publicfunctiongetOneField($field) { $this->setFields($field); $rs=$this->getOne(); return!empty($rs[$field])?$rs[$field]:''; } //获取数据集中所有某个字段的值 publicfunctiongetFields($field) { $this->setFields($field); $rs=$this->get(); $result=[]; foreach($rsas$v){ $result[]=$v[$field]; } unset($rs); return$result; } //清除查询条件 //防止干扰下次查询 publicfunctionclearQuery() { $this->fields='*'; $this->arrWhere=[]; $this->order=''; $this->arrOrder=[]; $this->limit=''; } //断开数据库连接 publicfunctionclose() { $this->link->close(); } //事务 //自动提交开关 publicfunctionautocommit($bool) { $this->link->autocommit($bool); } //事务完成提交 publicfunctioncommit() { $this->link->commit(); } //回滚 publicfunctionrollback() { $this->link->rollback(); } //输出错误sql语句 publicfunctionerror($sql) { //if(IS_TEST){} exit($sql); } }
更多关于PHP相关内容感兴趣的读者可查看本站专题:《php+mysqli数据库程序设计技巧总结》、《PHP基于pdo操作数据库技巧总结》、《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。