db_driver_mysqli_slave.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Discuz! Team
  4. * This is NOT a freeware, use is subject to license terms
  5. * https://license.discuz.vip
  6. */
  7. if(!defined('IN_DISCUZ')) {
  8. exit('Access Denied');
  9. }
  10. class db_driver_mysqli_slave extends db_driver_mysqli {
  11. public $slaveid = null;
  12. public $slavequery = 0;
  13. public $slaveexcept = false;
  14. public $excepttables = [];
  15. public $tablename = '';
  16. protected $_weighttable = [];
  17. public $serverid = null;
  18. function set_config($config) {
  19. parent::set_config($config);
  20. if($this->config['common']['slave_except_table']) {
  21. $this->excepttables = explode(',', str_replace(' ', '', $this->config['common']['slave_except_table']));
  22. }
  23. }
  24. public function table_name($tablename) {
  25. $this->tablename = $tablename;
  26. if(!$this->slaveexcept && $this->excepttables) {
  27. $this->slaveexcept = in_array($tablename, $this->excepttables, true);
  28. }
  29. $this->serverid = $this->map[$this->tablename] ?? 1;
  30. return $this->tablepre.$tablename;
  31. }
  32. protected function _slave_connect() {
  33. if(!empty($this->config[$this->serverid]['slave'])) {
  34. $this->_choose_slave();
  35. if($this->slaveid) {
  36. if(!isset($this->link[$this->slaveid])) {
  37. $this->connect($this->slaveid);
  38. }
  39. $this->slavequery++;
  40. $this->curlink = $this->link[$this->slaveid];
  41. }
  42. return true;
  43. } else {
  44. return false;
  45. }
  46. }
  47. protected function _choose_slave() {
  48. if(!isset($this->_weighttable[$this->serverid])) {
  49. foreach($this->config[$this->serverid]['slave'] as $key => $value) {
  50. $this->_weighttable[$this->serverid] .= str_repeat($key, 1 + intval($value['weight']));
  51. }
  52. }
  53. $sid = $this->_weighttable[$this->serverid][mt_rand(0, strlen($this->_weighttable[$this->serverid]) - 1)];
  54. $this->slaveid = $this->serverid.'_'.$sid;
  55. if(!isset($this->config[$this->slaveid])) {
  56. $this->config[$this->slaveid] = $this->config[$this->serverid]['slave'][$sid];
  57. }
  58. }
  59. protected function _master_connect() {
  60. if($this->serverid === null) {
  61. $this->serverid = 1;
  62. }
  63. if(!$this->link[$this->serverid]) {
  64. $this->connect($this->serverid);
  65. }
  66. $this->curlink = $this->link[$this->serverid];
  67. }
  68. public function query($sql, $silent = false, $unbuffered = false) {
  69. if(!(!$this->slaveexcept && strtoupper(substr($sql, 0, 6)) === 'SELECT' && !str_contains(strtoupper($sql), 'FOR UPDATE') && $this->_slave_connect())) {
  70. $this->_master_connect();
  71. }
  72. $this->tablename = '';
  73. $this->slaveexcept = false;
  74. return parent::query($sql, $silent, $unbuffered);
  75. }
  76. }