使用PHP实现Mysql读写分离


Posted in PHP onJune 28, 2013

本代码是从uchome的代码修改的,是因为要解决uchome的效率而处理的。这个思维其实很久就有了,只是一直没有去做,相信也有人有同样的想法,如果有类似的,那真的希望提出相关的建议。

封装的方式比较简单,增加了只读数据库连接的接口扩展,不使用只读数据库也不影响原代码使用。有待以后不断完善。。
为了方便,试试建立了google的一个项目:
http://code.google.com/p/mysql-rw-php/
希望给有需要的朋友带来帮助。

PHP实现的Mysql读写分离
主要特性:
1.简单的读写分离
2.一个主数据库,可以添加更多的只读数据库
3.读写分离但不用担心某些特性不支持
4.缺点:同时连接两个数据库
英文比较烂,也写几个字吧
php code for mysql read/write split
feature:
simply rw split
one master,can add more slaves
support all mysql feature
link to the master and slave at the same time
PHP代码:
mysql_rw_php.class.php

<?php
/****************************************
*** mysql-rw-php version 0.1 
*** code by hqlulu#gmail.com
*** http://www.aslibra.com
*** http://code.google.com/p/mysql-rw-php/
*** code modify from class_mysql.php (uchome)
****************************************/
class mysql_rw_php {
  //查询个数
  var $querynum = 0;
  //当前操作的数据库连接
  var $link = null;
  //字符集
  var $charset;
  //当前数据库
  var $cur_db = '';
  //是否存在有效的只读数据库连接
  var $ro_exist = false;
  //只读数据库连接
  var $link_ro = null;
  //读写数据库连接
  var $link_rw = null;
  function mysql_rw_php(){
  }
  function connect($dbhost, $dbuser, $dbpw, $dbname = '', $pconnect = 0, $halt = TRUE) {
    if($pconnect) {
      if(!$this->link = @mysql_pconnect($dbhost, $dbuser, $dbpw)) {
        $halt && $this->halt('Can not connect to MySQL server');
      }
    } else {
      if(!$this->link = @mysql_connect($dbhost, $dbuser, $dbpw)) {
        $halt && $this->halt('Can not connect to MySQL server');
      }
    }    //只读连接失败
    if(!$this->link && !$halt) return false;
    //未初始化rw时,第一个连接作为rw
    if($this->link_rw == null)
      $this->link_rw = $this->link;
    if($this->version() > '4.1') {
      if($this->charset) {
        @mysql_query("SET character_set_connection=$this->charset, character_set_results=$this->charset, character_set_client=binary", $this->link);
      }
      if($this->version() > '5.0.1') {
        @mysql_query("SET sql_mode=''", $this->link);
      }
    }
    if($dbname) {
      $this->select_db($dbname);
    }
  }
  //连接一个只读的mysql数据库
  function connect_ro($dbhost, $dbuser, $dbpw, $dbname = '', $pconnect = 0){
    if($this->link_rw == null)
      $this->link_rw = $this->link;
    $this->link = null;
    //不产生halt错误
    $this->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, false);
    if($this->link){
      //连接成功
      //echo "link ro sussess!<br>";
      $this->ro_exist = true;
      $this->link_ro = $this->link;
      if($this->cur_db){
        //如果已经选择过数据库则需要操作一次
        @mysql_select_db($this->cur_db, $this->link_ro);
      }
    }else{
      //连接失败
      //echo "link ro failed!<br>";
      $this->link = &$this->link_rw;
    }
  }
  //设置一系列只读数据库并且连接其中一个
  function set_ro_list($ro_list){
    if(is_array($ro_list)){
      //随机选择其中一个
      $link_ro = $ro_list[array_rand($ro_list)];
      $this->connect_ro($link_ro['dbhost'], $link_ro['dbuser'], $link_ro['dbpw']);
    }
  }
  function select_db($dbname) {
    //同时操作两个数据库连接
    $this->cur_db = $dbname;
    if($this->ro_exist){
      @mysql_select_db($dbname, $this->link_ro);
    }
    return @mysql_select_db($dbname, $this->link_rw);
  }
  function fetch_array($query, $result_type = MYSQL_ASSOC) {
    return mysql_fetch_array($query, $result_type);
  }
  function fetch_one_array($sql, $type = '') {
    $qr = $this->query($sql, $type);
    return $this->fetch_array($qr);
  }
  function query($sql, $type = '') {
    $this->link = &$this->link_rw;
    //判断是否select语句
    if($this->ro_exist && preg_match ("/^(\s*)select/i", $sql)){
      $this->link = &$this->link_ro;
    }
    $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?
      'mysql_unbuffered_query' : 'mysql_query';
    if(!($query = $func($sql, $this->link)) && $type != 'SILENT') {
      $this->halt('MySQL Query Error', $sql);
    }
    $this->querynum++;
    return $query;
  }
  function affected_rows() {
    return mysql_affected_rows($this->link);
  }
  function error() {
    return (($this->link) ? mysql_error($this->link) : mysql_error());
  }
  function errno() {
    return intval(($this->link) ? mysql_errno($this->link) : mysql_errno());
  }
  function result($query, $row) {
    $query = @mysql_result($query, $row);
    return $query;
  }
  function num_rows($query) {
    $query = mysql_num_rows($query);
    return $query;
  }
  function num_fields($query) {
    return mysql_num_fields($query);
  }
  function free_result($query) {
    return mysql_free_result($query);
  }
  function insert_id() {
    return ($id = mysql_insert_id($this->link)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);
  }
  function fetch_row($query) {
    $query = mysql_fetch_row($query);
    return $query;
  }
  function fetch_fields($query) {
    return mysql_fetch_field($query);
  }
  function version() {
    return mysql_get_server_info($this->link);
  }
  function close() {
    return mysql_close($this->link);
  }
  function halt($message = '', $sql = '') {
    $dberror = $this->error();
    $dberrno = $this->errno();
    echo "<div style=\"position:absolute;font-size:11px;font-family:verdana,arial;background:#EBEBEB;padding:0.5em;\">
        <b>MySQL Error</b><br>
        <b>Message</b>: $message<br>
        <b>SQL</b>: $sql<br>
        <b>Error</b>: $dberror<br>
        <b>Errno.</b>: $dberrno<br>
        </div>";
    exit();
  }
}
?>
PHP 相关文章推荐
PHP5中MVC结构学习
Oct 09 PHP
使用php+xslt在windows平台上
Oct 09 PHP
实用函数4
Nov 08 PHP
第六章 php目录与文件操作
Dec 30 PHP
深入解析php之sphinx
May 15 PHP
PHP设计模式之责任链模式的深入解析
Jun 13 PHP
ThinkPHP中redirect用法分析
Dec 05 PHP
初识laravel5
Mar 02 PHP
Yii2框架数据库简单的增删改查语法小结
Aug 31 PHP
php基于curl主动推送最新内容给百度收录的方法
Oct 14 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
May 08 PHP
PHP全局使用Laravel辅助函数dd
Dec 26 PHP
win7下memCache的安装过程(具体操作步骤)
Jun 28 #PHP
浅析memcache启动以及telnet命令详解
Jun 28 #PHP
浅析HTTP消息头网页缓存控制以及header常用指令介绍
Jun 28 #PHP
深入apache配置文件httpd.conf的部分参数说明
Jun 28 #PHP
浅析php变量修饰符static的使用
Jun 28 #PHP
解析php如何将日志写进syslog
Jun 28 #PHP
解析PHP中VC6 X86和VC9 X86的区别及 Non Thread Safe的意思
Jun 28 #PHP
You might like
安装PHP可能遇到的问题“无法载入mysql扩展” 的解决方法
2007/04/16 PHP
mysqli_set_charset和SET NAMES使用抉择及优劣分析
2013/01/13 PHP
解析thinkphp import 文件内容变量失效的问题
2013/06/20 PHP
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
2014/08/18 PHP
CodeIgniter实现从网站抓取图片并自动下载到文件夹里的方法
2015/06/17 PHP
js复制到剪切板的实例方法
2013/06/28 Javascript
Node.js开源应用框架HapiJS介绍
2015/01/14 Javascript
JQuery节点元素属性操作方法
2015/06/11 Javascript
javascript回到顶部特效
2016/07/30 Javascript
输入法的回车与消息发送快捷键回车的冲突解决方法
2016/08/09 Javascript
tangram.js库实现js类的方式实例分析
2018/01/06 Javascript
vue input实现点击按钮文字增删功能示例
2019/01/29 Javascript
vue.js中ref和$refs的使用及示例讲解
2019/08/14 Javascript
Python中apply函数的用法实例教程
2014/07/31 Python
Python制作CSDN免积分下载器
2015/03/10 Python
Python删除Java源文件中全部注释的实现方法
2017/08/30 Python
利用Tkinter和matplotlib两种方式画饼状图的实例
2017/11/06 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
2019/01/08 Python
解决python3.5 正常安装 却不能直接使用Tkinter包的问题
2019/02/22 Python
django 中QuerySet特性功能详解
2019/07/25 Python
Python Django Vue 项目创建过程详解
2019/07/29 Python
Python中模块(Module)和包(Package)的区别详解
2019/08/07 Python
tensorflow 初始化未初始化的变量实例
2020/02/06 Python
pandas和spark dataframe互相转换实例详解
2020/02/18 Python
使用python+poco+夜神模拟器进行自动化测试实例
2020/04/23 Python
css3圆角边框和边框阴影示例
2014/05/05 HTML / CSS
英国票务网站:Ticketmaster英国
2018/08/27 全球购物
写好求职信第一句话的技巧
2013/10/26 职场文书
小学五年级学生评语
2014/04/22 职场文书
个人授权委托书样本
2014/09/13 职场文书
专题民主生活会对照检查材料思想汇报
2014/09/29 职场文书
国情备忘录观后感
2015/06/04 职场文书
2016年教师学习教师法心得体会
2016/01/20 职场文书
2016年母亲节广告语
2016/01/28 职场文书
python数字转对应中文的方法总结
2021/08/02 Python
【海涛解说】pis亲自推荐,其实你从来不会玩NW
2022/04/01 DOTA