db.php 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. <?php
  2. class mysql_db
  3. {
  4. var $link_id = NULL;
  5. var $settings = array();
  6. var $queryCount = 0;
  7. var $queryTime = '';
  8. var $queryLog = array();
  9. var $max_cache_time = 600; // 最大的缓存时间,以秒为单位
  10. var $cache_data_dir = 'public/runtime/app/db_caches/';
  11. var $root_path = '';
  12. var $error_message = array();
  13. var $platform = 'OTHER';
  14. var $version = '';
  15. var $dbhash = '';
  16. var $starttime = 0;
  17. var $timeline = 0;
  18. var $timezone = 0;
  19. var $mysql_config_cache_file_time = 0;
  20. var $mysql_disable_cache_tables = array(); // 不允许被缓存的表,遇到将不会进行缓存
  21. var $trans_status = false;//true,当前连接已经开启事务;false,未开启事务
  22. var $query_link = null;//只读连接
  23. function __construct($dbhost, $dbuser, $dbpw, $dbname = '', $charset = 'utf8', $pconnect = 0, $quiet = 0)
  24. {
  25. $this->mysql_db($dbhost, $dbuser, $dbpw, $dbname, $charset, $pconnect, $quiet);
  26. }
  27. function mysql_db($dbhost, $dbuser, $dbpw, $dbname = '', $charset = 'utf8', $pconnect = 0, $quiet = 0)
  28. {
  29. if (defined('APP_ROOT_PATH') && !$this->root_path)
  30. {
  31. $this->root_path = APP_ROOT_PATH;
  32. }
  33. if ($this->root_path == ''){
  34. $this->root_path = str_replace('system/db/db.php', '', str_replace('\\', '/', __FILE__));
  35. }
  36. $this->settings = array(
  37. 'dbhost' => $dbhost,
  38. 'dbuser' => $dbuser,
  39. 'dbpw' => $dbpw,
  40. 'dbname' => $dbname,
  41. 'charset' => $charset,
  42. 'pconnect' => $pconnect
  43. );
  44. }
  45. /**
  46. * 随机获得一个只读数据库连接
  47. * @param unknown_type $pid
  48. */
  49. function connect_readdb($charset = 'utf8')
  50. {
  51. if ($this->query_link != null){
  52. return $this->query_link;
  53. }else{
  54. $c = count($GLOBALS['distribution_cfg']['DB_DISTRIBUTION']);
  55. if($c==0){
  56. return null;
  57. }else{
  58. //还没有分配,只读数据库连接,则随机分配一个
  59. $c = $c-1;
  60. $pid = mt_rand(0, $c);
  61. $dbhost = $GLOBALS['distribution_cfg']['DB_DISTRIBUTION'][$pid]['DB_HOST'];
  62. $dbport = $GLOBALS['distribution_cfg']['DB_DISTRIBUTION'][$pid]['DB_PORT'];
  63. $dbuser = $GLOBALS['distribution_cfg']['DB_DISTRIBUTION'][$pid]['DB_USER'];
  64. $dbpw = $GLOBALS['distribution_cfg']['DB_DISTRIBUTION'][$pid]['DB_PWD'];
  65. $dbname = $GLOBALS['distribution_cfg']['DB_DISTRIBUTION'][$pid]['DB_NAME'];
  66. $dbhost.=":".$dbport;
  67. $link_db = null;
  68. if (PHP_VERSION >= '4.2')
  69. {
  70. $link_db = @mysql_connect($dbhost, $dbuser, $dbpw, true);
  71. }
  72. else
  73. {
  74. $link_db = @mysql_connect($dbhost, $dbuser, $dbpw);
  75. }
  76. if($link_db)
  77. {
  78. $this->version = mysql_get_server_info($link_db);
  79. /* 如果mysql 版本是 4.1+ 以上,需要对字符集进行初始化 */
  80. if ($this->version > '4.1')
  81. {
  82. if ($charset != 'latin1')
  83. {
  84. mysql_query("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary", $this->link_list[$pid]);
  85. }
  86. if ($this->version > '5.0.1')
  87. {
  88. mysql_query("SET sql_mode=''", $link_db);
  89. }
  90. }
  91. if ($dbname)
  92. {
  93. if (mysql_select_db($dbname, $link_db) === false )
  94. {
  95. @mysql_close($link_db);
  96. $link_db = null;
  97. }
  98. else
  99. {
  100. return true;
  101. }
  102. }
  103. else
  104. {
  105. @mysql_close($link_db);
  106. $link_db = null;
  107. }
  108. }
  109. $this->query_link = $link_db;
  110. //logger::write("db_distribution_init_err:".$pid,logger::ERR,logger::FILE,"db_distribution");
  111. return $link_db;
  112. }
  113. }
  114. }
  115. function connect($dbhost, $dbuser, $dbpw, $dbname = '', $charset = 'utf8', $pconnect = 0, $quiet = 0)
  116. {
  117. if ($pconnect) {
  118. if (! ($this->link_id = @mysql_pconnect ( $dbhost, $dbuser, $dbpw ))) {
  119. if (! $quiet) {
  120. $this->ErrorMsg ( "Can't pConnect MySQL Server($dbhost)!" );
  121. }
  122. return false;
  123. }
  124. } else {
  125. if (PHP_VERSION >= '4.2') {
  126. $this->link_id = @mysql_connect ( $dbhost, $dbuser, $dbpw, true );
  127. } else {
  128. $this->link_id = @mysql_connect ( $dbhost, $dbuser, $dbpw );
  129. mt_srand ( ( double ) microtime () * 1000000 ); // 对 PHP 4.2
  130. // 以下的版本进行随机数函数的初始化工作
  131. }
  132. if (! $this->link_id) {
  133. if (! $quiet) {
  134. $this->ErrorMsg ( "Can't Connect MySQL Server($dbhost)!" );
  135. }
  136. return false;
  137. }
  138. }
  139. $this->dbhash = md5 ( $this->root_path . $dbhost . $dbuser . $dbpw . $dbname );
  140. $this->version = mysql_get_server_info ( $this->link_id );
  141. /* 如果mysql 版本是 4.1+ 以上,需要对字符集进行初始化 */
  142. if ($this->version > '4.1') {
  143. if ($charset != 'latin1') {
  144. mysql_query ( "SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary", $this->link_id );
  145. }
  146. if ($this->version > '5.0.1') {
  147. mysql_query ( "SET sql_mode=''", $this->link_id );
  148. }
  149. }
  150. /*
  151. $sqlcache_config_file = $this->root_path . $this->cache_data_dir . 'sqlcache_config_file_' . $this->dbhash . '.php';
  152. $this->starttime = time ();
  153. if (! file_exists ( $sqlcache_config_file )) {
  154. if ($dbhost != '.') {
  155. $result = mysql_query ( "SHOW VARIABLES LIKE 'basedir'", $this->link_id );
  156. $row = mysql_fetch_assoc ( $result );
  157. if (! empty ( $row ['Value'] {1} ) && $row ['Value'] {1} == ':' && ! empty ( $row ['Value'] {2} ) && $row ['Value'] {2} == "\\") {
  158. $this->platform = 'WINDOWS';
  159. } else {
  160. $this->platform = 'OTHER';
  161. }
  162. } else {
  163. $this->platform = 'WINDOWS';
  164. }
  165. if ($this->platform == 'OTHER' && ($dbhost != '.' && strtolower ( $dbhost ) != 'localhost:3306' && $dbhost != '127.0.0.1:3306') || (PHP_VERSION >= '5.1' && date_default_timezone_get () == 'UTC')) {
  166. $result = mysql_query ( "SELECT UNIX_TIMESTAMP() AS timeline, UNIX_TIMESTAMP('" . date ( 'Y-m-d H:i:s', $this->starttime ) . "') AS timezone", $this->link_id );
  167. $row = mysql_fetch_assoc ( $result );
  168. if ($dbhost != '.' && strtolower ( $dbhost ) != 'localhost:3306' && $dbhost != '127.0.0.1:3306') {
  169. $this->timeline = $this->starttime - $row ['timeline'];
  170. }
  171. if (PHP_VERSION >= '5.1' && date_default_timezone_get () == 'UTC') {
  172. $this->timezone = $this->starttime - $row ['timezone'];
  173. }
  174. }
  175. $content = '<' . "?php\r\n" . '$this->mysql_config_cache_file_time = ' . $this->starttime . ";\r\n" . '$this->timeline = ' . $this->timeline . ";\r\n" . '$this->timezone = ' . $this->timezone . ";\r\n" . '$this->platform = ' . "'" . $this->platform . "';\r\n?" . '>';
  176. @file_put_contents ( $sqlcache_config_file, $content );
  177. }
  178. @include ($sqlcache_config_file);
  179. */
  180. /* 选择数据库 */
  181. if ($dbname) {
  182. if (mysql_select_db ( $dbname, $this->link_id ) === false) {
  183. if (! $quiet) {
  184. $this->ErrorMsg ( "Can't select MySQL database($dbname)!" );
  185. }
  186. return false;
  187. } else {
  188. return true;
  189. }
  190. } else {
  191. return true;
  192. }
  193. }
  194. function select_database($dbname)
  195. {
  196. return mysql_select_db($dbname, $this->link_id);
  197. }
  198. function set_mysql_charset($charset)
  199. {
  200. /* 如果mysql 版本是 4.1+ 以上,需要对字符集进行初始化 */
  201. if ($this->version > '4.1')
  202. {
  203. if (in_array(strtolower($charset), array('gbk', 'big5', 'utf-8', 'utf8')))
  204. {
  205. $charset = str_replace('-', '', $charset);
  206. }
  207. if ($charset != 'latin1')
  208. {
  209. mysql_query("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary", $this->link_id);
  210. }
  211. }
  212. }
  213. function fetch_array($query, $result_type = MYSQL_ASSOC)
  214. {
  215. return mysql_fetch_array($query, $result_type);
  216. }
  217. function query($sql, $type = "SILENT", $is_read_db = false) {
  218. if (! IS_DEBUG&&!SHOW_DEBUG)
  219. $type = "SILENT";
  220. if ($is_read_db){
  221. if ($this->query_link === NULL) {
  222. $this->query_link = $this->connect_readdb();
  223. }
  224. if ($this->query_link === NULL) {
  225. if ($this->link_id === NULL) {
  226. $this->connect ( $this->settings ['dbhost'], $this->settings ['dbuser'], $this->settings ['dbpw'], $this->settings ['dbname'], $this->settings ['charset'], $this->settings ['pconnect'] );
  227. $this->settings = array ();
  228. }
  229. $this->query_link = $this->link_id;
  230. }
  231. $query_link = $this->query_link;
  232. }else{
  233. if ($this->link_id === NULL) {
  234. $this->connect ( $this->settings ['dbhost'], $this->settings ['dbuser'], $this->settings ['dbpw'], $this->settings ['dbname'], $this->settings ['charset'], $this->settings ['pconnect'] );
  235. $this->settings = array ();
  236. }
  237. $query_link = $this->link_id;
  238. }
  239. /* 当当前的时间大于类初始化时间的时候,自动执行 ping 这个自动重新连接操作 */
  240. if (PHP_VERSION >= '4.3' && time () > $this->starttime + 1) {
  241. mysql_ping ( $query_link );
  242. }
  243. if (PHP_VERSION >= '5.0.0') {
  244. $begin_query_time = microtime ( true );
  245. } else {
  246. $begin_query_time = microtime ();
  247. }
  248. if (! ($query = mysql_query ( $sql, $query_link )) && $type != 'SILENT') {
  249. $message['message'] = 'MySQL Query Error';
  250. //if ($pid)
  251. //$message['message'] = 'MySQL Query Error:' . $pid;
  252. $message['sql'] = $sql;
  253. $message['error'] = mysql_error ( $query_link );
  254. $message['errno'] = mysql_errno ( $query_link );
  255. $this->error_message[] = $message;
  256. $this->ErrorMsg ($message['message'].":".$message['error']."<br />errno:".$message['errno']."<br />sql:".$message['sql']);
  257. return false;
  258. }
  259. if (PHP_VERSION >= '5.0.0') {
  260. $query_time = microtime ( true ) - $begin_query_time;
  261. } else {
  262. list ( $now_usec, $now_sec ) = explode ( ' ', microtime () );
  263. list ( $start_usec, $start_sec ) = explode ( ' ', $begin_query_time );
  264. $query_time = ($now_sec - $start_sec) + ($now_usec - $start_usec);
  265. }
  266. $this->queryTime += $query_time;
  267. if ($this->queryCount ++ <= 99) {
  268. $this->queryLog [] = $sql . " " . $query_time;
  269. }
  270. // echo
  271. // $sql."<br/><br/>======================================<br/><br/>";
  272. return $query;
  273. }
  274. function affected_rows()
  275. {
  276. return mysql_affected_rows($this->link_id);
  277. }
  278. function error()
  279. {
  280. return mysql_error($this->link_id);
  281. }
  282. function errno()
  283. {
  284. return mysql_errno($this->link_id);
  285. }
  286. function result($query, $row)
  287. {
  288. return @mysql_result($query, $row);
  289. }
  290. function num_rows($query)
  291. {
  292. return mysql_num_rows($query);
  293. }
  294. function num_fields($query)
  295. {
  296. return mysql_num_fields($query);
  297. }
  298. function free_result($query)
  299. {
  300. return mysql_free_result($query);
  301. }
  302. function insert_id()
  303. {
  304. return mysql_insert_id($this->link_id);
  305. }
  306. function fetchRow($query)
  307. {
  308. return mysql_fetch_assoc($query);
  309. }
  310. function fetch_fields($query)
  311. {
  312. return mysql_fetch_field($query);
  313. }
  314. function version()
  315. {
  316. return $this->version;
  317. }
  318. function ping()
  319. {
  320. if (PHP_VERSION >= '4.3')
  321. {
  322. return mysql_ping($this->link_id);
  323. }
  324. else
  325. {
  326. return false;
  327. }
  328. }
  329. function escape_string($unescaped_string)
  330. {
  331. if (PHP_VERSION >= '4.3')
  332. {
  333. return mysql_real_escape_string($unescaped_string);
  334. }
  335. else
  336. {
  337. return mysql_escape_string($unescaped_string);
  338. }
  339. }
  340. function close()
  341. {
  342. return mysql_close($this->link_id);
  343. }
  344. function ErrorMsg($message = '', $sql = '')
  345. {
  346. if ($message)
  347. {
  348. echo "<b>error info</b>: $message\n\n<br /><br />";
  349. }
  350. else
  351. {
  352. echo "<b>MySQL server error report:";
  353. print_r($this->error_message);
  354. //echo "<br /><br /><a href='http://faq.comsenz.com/?type=mysql&dberrno=" . $this->error_message[3]['errno'] . "&dberror=" . urlencode($this->error_message[2]['error']) . "' target='_blank'>http://faq.comsenz.com/</a>";
  355. }
  356. exit;
  357. }
  358. /* 仿真 Adodb 函数 */
  359. function selectLimit($sql, $num, $start = 0)
  360. {
  361. if ($start == 0)
  362. {
  363. $sql .= ' LIMIT ' . $num;
  364. }
  365. else
  366. {
  367. $sql .= ' LIMIT ' . $start . ', ' . $num;
  368. }
  369. return $this->query($sql);
  370. }
  371. /**
  372. * 检测查询语句中的表是否支持查询缓存
  373. * @param unknown_type $sql true:即时查询 false:缓存查询
  374. */
  375. function is_immediate($sql,$is_immediate)
  376. {
  377. /*
  378. if(!$is_immediate)
  379. {
  380. if(in_array(APP_INDEX, $GLOBALS['distribution_cfg']['DB_CACHE_APP'])&&$GLOBALS['distribution_cfg']['CACHE_TYPE']!="File")
  381. {
  382. return false;
  383. }
  384. else
  385. {
  386. return true;
  387. }
  388. }
  389. else
  390. {
  391. if(in_array(APP_INDEX, $GLOBALS['distribution_cfg']['DB_CACHE_APP'])&&$GLOBALS['distribution_cfg']['CACHE_TYPE']!="File")
  392. {
  393. preg_match_all("/from\s+([\S]+)/", $sql,$matches);
  394. if($matches)
  395. {
  396. foreach($matches[1] as $k=>$v)
  397. {
  398. $table = str_replace(DB_PREFIX, "", $v);
  399. if(in_array($table, $GLOBALS['distribution_cfg']['DB_CACHE_TABLES']))
  400. {
  401. return false;
  402. }
  403. }
  404. }
  405. }
  406. }
  407. */
  408. return $is_immediate;
  409. }
  410. /**
  411. *
  412. * @param unknown_type $sql
  413. * @param unknown_type $is_immediate 是否为立即查 询,默认为true,则再按缓存配置读取, false时直接按指定方式
  414. * @return unknown|Ambigous <>|string|boolean
  415. */
  416. function getOne($sql,$is_immediate = true,$is_read_db = false)
  417. {
  418. $immediate = $this->is_immediate($sql,$is_immediate);
  419. $res = false;
  420. if(!IS_DEBUG&&!$immediate)
  421. {
  422. $GLOBALS['cache']->set_dir(APP_ROOT_PATH.$this->cache_data_dir);
  423. $res = $GLOBALS['cache']->get($sql);
  424. }
  425. if($res!==false)
  426. {
  427. return $res;
  428. }
  429. $res = $this->query($sql,"",$is_read_db);
  430. if ($res !== false)
  431. {
  432. $row = mysql_fetch_row($res);
  433. if ($row !== false)
  434. {
  435. if(!IS_DEBUG&&!$immediate)
  436. {
  437. $GLOBALS['cache']->set_dir(APP_ROOT_PATH.$this->cache_data_dir);
  438. $GLOBALS['cache']->set($sql,$row[0],$this->max_cache_time);
  439. }
  440. return $row[0];
  441. }
  442. else
  443. {
  444. if(!IS_DEBUG&&!$immediate)
  445. {
  446. $GLOBALS['cache']->set_dir(APP_ROOT_PATH.$this->cache_data_dir);
  447. $GLOBALS['cache']->set($sql,'',$this->max_cache_time);
  448. }
  449. return '';
  450. }
  451. }
  452. else
  453. {
  454. if(!IS_DEBUG&&!$immediate)
  455. {
  456. $GLOBALS['cache']->set_dir(APP_ROOT_PATH.$this->cache_data_dir);
  457. $GLOBALS['cache']->set($sql,'',$this->max_cache_time);
  458. }
  459. return false;
  460. }
  461. }
  462. function getOneCached($sql, $cached = 'FILEFIRST',$is_read_db = false)
  463. {
  464. $cachefirst = ($cached == 'FILEFIRST' || ($cached == 'MYSQLFIRST' && $this->platform != 'WINDOWS')) && $this->max_cache_time;
  465. if (!$cachefirst)
  466. {
  467. return $this->getOne($sql, true,$is_read_db);
  468. }
  469. else
  470. {
  471. $result = $this->getSqlCacheData($sql, $cached);
  472. if (empty($result['storecache']) == true)
  473. {
  474. return $result['data'];
  475. }
  476. }
  477. $arr = $this->getOne($sql, true);
  478. if ($arr !== false && $cachefirst)
  479. {
  480. $this->setSqlCacheData($result, $arr);
  481. }
  482. return $arr;
  483. }
  484. /**
  485. *
  486. * @param string $sql
  487. * @param boolean $is_immediate true:即时查询 false:缓存查询
  488. * @param boolean $is_read_db true:从只读数据库中取; false:从主数据库中取数据
  489. * @return unknown|multitype:multitype: |boolean
  490. */
  491. function getAll($sql,$is_immediate=true,$is_read_db = false)
  492. {
  493. $res = false;
  494. if($res!==false)
  495. {
  496. return $res;
  497. }
  498. $res = $this->query($sql,"",$is_read_db);
  499. if ($res !== false)
  500. {
  501. $arr = array();
  502. while ($row = mysql_fetch_assoc($res))
  503. {
  504. $arr[] = $row;
  505. }
  506. return $arr;
  507. }
  508. else
  509. {
  510. return false;
  511. }
  512. }
  513. function getAllCached($sql, $cached = 'FILEFIRST',$is_read_db)
  514. {
  515. $cachefirst = ($cached == 'FILEFIRST' || ($cached == 'MYSQLFIRST' && $this->platform != 'WINDOWS')) && $this->max_cache_time;
  516. if (!$cachefirst)
  517. {
  518. return $this->getAll($sql,true,$is_read_db );
  519. }
  520. else
  521. {
  522. $result = $this->getSqlCacheData($sql, $cached);
  523. if (empty($result['storecache']) == true)
  524. {
  525. return $result['data'];
  526. }
  527. }
  528. $arr = $this->getAll($sql,true,$is_read_db);
  529. if ($arr !== false && $cachefirst)
  530. {
  531. $this->setSqlCacheData($result, $arr);
  532. }
  533. return $arr;
  534. }
  535. function getRow($sql,$is_immediate=true,$is_read_db = false)
  536. {
  537. $immediate = $this->is_immediate($sql,$is_immediate);
  538. $res = false;
  539. if(!IS_DEBUG&&!$immediate)
  540. {
  541. $GLOBALS['cache']->set_dir(APP_ROOT_PATH.$this->cache_data_dir);
  542. $res = $GLOBALS['cache']->get($sql);
  543. }
  544. if($res!==false)
  545. {
  546. return $res;
  547. }
  548. $res = $this->query($sql,"",$is_read_db);
  549. if ($res !== false)
  550. {
  551. $res = mysql_fetch_assoc($res);
  552. if(!IS_DEBUG&&!$immediate)
  553. {
  554. $GLOBALS['cache']->set_dir(APP_ROOT_PATH.$this->cache_data_dir);
  555. if($res)
  556. $GLOBALS['cache']->set($sql,$res,$this->max_cache_time);
  557. else
  558. $GLOBALS['cache']->set($sql,'',$this->max_cache_time);
  559. }
  560. return $res;
  561. }
  562. else
  563. {
  564. if(!IS_DEBUG&&!$immediate)
  565. {
  566. $GLOBALS['cache']->set_dir(APP_ROOT_PATH.$this->cache_data_dir);
  567. $GLOBALS['cache']->set($sql,'',$this->max_cache_time);
  568. }
  569. return false;
  570. }
  571. }
  572. function getRowCached($sql, $cached = 'FILEFIRST',$is_read_db = false)
  573. {
  574. $cachefirst = ($cached == 'FILEFIRST' || ($cached == 'MYSQLFIRST' && $this->platform != 'WINDOWS')) && $this->max_cache_time;
  575. if (!$cachefirst)
  576. {
  577. return $this->getRow($sql, true,$is_read_db);
  578. }
  579. else
  580. {
  581. $result = $this->getSqlCacheData($sql, $cached);
  582. if (empty($result['storecache']) == true)
  583. {
  584. return $result['data'];
  585. }
  586. }
  587. $arr = $this->getRow($sql, true,$is_read_db);
  588. if ($arr !== false && $cachefirst)
  589. {
  590. $this->setSqlCacheData($result, $arr);
  591. }
  592. return $arr;
  593. }
  594. /**
  595. * 针对数据的查询缓存返回的当前时间戳,用于查询
  596. * @param unknown_type $time
  597. */
  598. function getCacheTime($time)
  599. {
  600. return intval($time/$this->max_cache_time)*$this->max_cache_time;
  601. }
  602. function getCol($sql,$is_read_db = false)
  603. {
  604. $res = $this->query($sql,"",$is_read_db);
  605. if ($res !== false)
  606. {
  607. $arr = array();
  608. while ($row = mysql_fetch_row($res))
  609. {
  610. $arr[] = $row[0];
  611. }
  612. return $arr;
  613. }
  614. else
  615. {
  616. return false;
  617. }
  618. }
  619. function getColCached($sql, $cached = 'FILEFIRST',$is_read_db = false)
  620. {
  621. $cachefirst = ($cached == 'FILEFIRST' || ($cached == 'MYSQLFIRST' && $this->platform != 'WINDOWS')) && $this->max_cache_time;
  622. if (!$cachefirst)
  623. {
  624. return $this->getCol($sql,$is_read_db);
  625. }
  626. else
  627. {
  628. $result = $this->getSqlCacheData($sql, $cached);
  629. if (empty($result['storecache']) == true)
  630. {
  631. return $result['data'];
  632. }
  633. }
  634. $arr = $this->getCol($sql,$is_read_db);
  635. if ($arr !== false && $cachefirst)
  636. {
  637. $this->setSqlCacheData($result, $arr);
  638. }
  639. return $arr;
  640. }
  641. function autoExecute($table, $field_values, $mode = 'INSERT', $where = '', $querymode = '')
  642. {
  643. $field_names = $this->getCol('DESC ' . $table);
  644. $sql = '';
  645. if ($mode == 'INSERT')
  646. {
  647. $fields = $values = array();
  648. foreach ($field_names AS $value)
  649. {
  650. if (@array_key_exists($value, $field_values) == true)
  651. {
  652. $fields[] = $value;
  653. $field_values[$value] = stripslashes($field_values[$value]);
  654. $values[] = "'" . addslashes($field_values[$value]) . "'";
  655. }
  656. }
  657. if (!empty($fields))
  658. {
  659. $sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
  660. }
  661. }
  662. else
  663. {
  664. $sets = array();
  665. foreach ($field_names AS $value)
  666. {
  667. if (array_key_exists($value, $field_values) == true)
  668. {
  669. $field_values[$value] = stripslashes($field_values[$value]);
  670. $sets[] = $value . " = '" . addslashes($field_values[$value]) . "'";
  671. }
  672. }
  673. if (!empty($sets))
  674. {
  675. $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $sets) . ' WHERE ' . $where;
  676. }
  677. }
  678. if ($sql)
  679. {
  680. return $this->query($sql, $querymode);
  681. }
  682. else
  683. {
  684. return false;
  685. }
  686. }
  687. function autoReplace($table, $field_values, $update_values, $where = '', $querymode = '')
  688. {
  689. $field_descs = $this->getAll('DESC ' . $table);
  690. $primary_keys = array();
  691. foreach ($field_descs AS $value)
  692. {
  693. $field_names[] = $value['Field'];
  694. if ($value['Key'] == 'PRI')
  695. {
  696. $primary_keys[] = $value['Field'];
  697. }
  698. }
  699. $fields = $values = array();
  700. foreach ($field_names AS $value)
  701. {
  702. if (array_key_exists($value, $field_values) == true)
  703. {
  704. $fields[] = $value;
  705. $values[] = "'" . $field_values[$value] . "'";
  706. }
  707. }
  708. $sets = array();
  709. foreach ($update_values AS $key => $value)
  710. {
  711. if (array_key_exists($key, $field_values) == true)
  712. {
  713. if (is_int($value) || is_float($value))
  714. {
  715. $sets[] = $key . ' = ' . $key . ' + ' . $value;
  716. }
  717. else
  718. {
  719. $sets[] = $key . " = '" . $value . "'";
  720. }
  721. }
  722. }
  723. $sql = '';
  724. if (empty($primary_keys))
  725. {
  726. if (!empty($fields))
  727. {
  728. $sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
  729. }
  730. }
  731. else
  732. {
  733. if ($this->version() >= '4.1')
  734. {
  735. if (!empty($fields))
  736. {
  737. $sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
  738. if (!empty($sets))
  739. {
  740. $sql .= 'ON DUPLICATE KEY UPDATE ' . implode(', ', $sets);
  741. }
  742. }
  743. }
  744. else
  745. {
  746. if (empty($where))
  747. {
  748. $where = array();
  749. foreach ($primary_keys AS $value)
  750. {
  751. if (is_numeric($value))
  752. {
  753. $where[] = $value . ' = ' . $field_values[$value];
  754. }
  755. else
  756. {
  757. $where[] = $value . " = '" . $field_values[$value] . "'";
  758. }
  759. }
  760. $where = implode(' AND ', $where);
  761. }
  762. if ($where && (!empty($sets) || !empty($fields)))
  763. {
  764. if (intval($this->getOne("SELECT COUNT(*) FROM $table WHERE $where")) > 0)
  765. {
  766. if (!empty($sets))
  767. {
  768. $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $sets) . ' WHERE ' . $where;
  769. }
  770. }
  771. else
  772. {
  773. if (!empty($fields))
  774. {
  775. $sql = 'REPLACE INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
  776. }
  777. }
  778. }
  779. }
  780. }
  781. if ($sql)
  782. {
  783. return $this->query($sql, $querymode);
  784. }
  785. else
  786. {
  787. return false;
  788. }
  789. }
  790. function setMaxCacheTime($second)
  791. {
  792. $this->max_cache_time = $second;
  793. }
  794. function getMaxCacheTime()
  795. {
  796. return $this->max_cache_time;
  797. }
  798. function getSqlCacheData($sql, $cached = '')
  799. {
  800. $sql = trim($sql);
  801. $result = array();
  802. $result['filename'] = $this->root_path . $this->cache_data_dir . 'sqlcache_' . abs(crc32($this->dbhash . $sql)) . '_' . md5($this->dbhash . $sql) . '.php';
  803. $result['data'] = $GLOBALS['cache']->get($result['filename']);
  804. if($result['data']===false)
  805. {
  806. $result['storecache'] = true;
  807. }
  808. else
  809. {
  810. $result['storecache'] = false;
  811. }
  812. return $result;
  813. }
  814. function setSqlCacheData($result, $data)
  815. {
  816. if ($result['storecache'] === true && $result['filename'])
  817. {
  818. $GLOBALS['cache']->set($result['filename'],$data,$this->max_cache_time);
  819. }
  820. }
  821. /* 获取 SQL 语句中最后更新的表的时间,有多个表的情况下,返回最新的表的时间 */
  822. function table_lastupdate($tables)
  823. {
  824. if ($this->link_id === NULL)
  825. {
  826. $this->connect($this->settings['dbhost'], $this->settings['dbuser'], $this->settings['dbpw'], $this->settings['dbname'], $this->settings['charset'], $this->settings['pconnect']);
  827. $this->settings = array();
  828. }
  829. $lastupdatetime = '0000-00-00 00:00:00';
  830. $tables = str_replace('`', '', $tables);
  831. $this->mysql_disable_cache_tables = str_replace('`', '', $this->mysql_disable_cache_tables);
  832. foreach ($tables AS $table)
  833. {
  834. if (in_array($table, $this->mysql_disable_cache_tables) == true)
  835. {
  836. $lastupdatetime = '2037-12-31 23:59:59';
  837. break;
  838. }
  839. if (strstr($table, '.') != NULL)
  840. {
  841. $tmp = explode('.', $table);
  842. $sql = 'SHOW TABLE STATUS FROM `' . trim($tmp[0]) . "` LIKE '" . trim($tmp[1]) . "'";
  843. }
  844. else
  845. {
  846. $sql = "SHOW TABLE STATUS LIKE '" . trim($table) . "'";
  847. }
  848. $result = mysql_query($sql, $this->link_id);
  849. $row = mysql_fetch_assoc($result);
  850. if ($row['Update_time'] > $lastupdatetime)
  851. {
  852. $lastupdatetime = $row['Update_time'];
  853. }
  854. }
  855. $lastupdatetime = strtotime($lastupdatetime) - $this->timezone + $this->timeline;
  856. return $lastupdatetime;
  857. }
  858. function get_table_name($query_item)
  859. {
  860. $query_item = trim($query_item);
  861. $table_names = array();
  862. /* 判断语句中是不是含有 JOIN */
  863. if (stristr($query_item, ' JOIN ') == '')
  864. {
  865. /* 解析一般的 SELECT FROM 语句 */
  866. if (preg_match('/^SELECT.*?FROM\s*((?:`?\w+`?\s*\.\s*)?`?\w+`?(?:(?:\s*AS)?\s*`?\w+`?)?(?:\s*,\s*(?:`?\w+`?\s*\.\s*)?`?\w+`?(?:(?:\s*AS)?\s*`?\w+`?)?)*)/is', $query_item, $table_names))
  867. {
  868. $table_names = preg_replace('/((?:`?\w+`?\s*\.\s*)?`?\w+`?)[^,]*/', '\1', $table_names[1]);
  869. return preg_split('/\s*,\s*/', $table_names);
  870. }
  871. }
  872. else
  873. {
  874. /* 对含有 JOIN 的语句进行解析 */
  875. if (preg_match('/^SELECT.*?FROM\s*((?:`?\w+`?\s*\.\s*)?`?\w+`?)(?:(?:\s*AS)?\s*`?\w+`?)?.*?JOIN.*$/is', $query_item, $table_names))
  876. {
  877. $other_table_names = array();
  878. preg_match_all('/JOIN\s*((?:`?\w+`?\s*\.\s*)?`?\w+`?)\s*/i', $query_item, $other_table_names);
  879. return array_merge(array($table_names[1]), $other_table_names[1]);
  880. }
  881. }
  882. return $table_names;
  883. }
  884. /* 设置不允许进行缓存的表 */
  885. function set_disable_cache_tables($tables)
  886. {
  887. if (!is_array($tables))
  888. {
  889. $tables = explode(',', $tables);
  890. }
  891. foreach ($tables AS $table)
  892. {
  893. $this->mysql_disable_cache_tables[] = $table;
  894. }
  895. array_unique($this->mysql_disable_cache_tables);
  896. }
  897. /**
  898. * 判断当前连接是否,已经开启事务
  899. */
  900. function InTransaction(){
  901. return $this->trans_status;
  902. }
  903. /**
  904. * 开启事务
  905. * return boolean $pInTrans
  906. */
  907. function StartTrans()
  908. {
  909. $pInTrans = true;
  910. if ($this->InTransaction()){
  911. $pInTrans = false;
  912. }else{
  913. $this->query("start transaction");
  914. $this->trans_status = true;
  915. $pInTrans = true;
  916. }
  917. return $pInTrans;
  918. }
  919. /**
  920. * 提交事务
  921. * @param boolean $pInTrans
  922. */
  923. function Commit($pInTrans)
  924. {
  925. if ($pInTrans && $this->InTransaction()){
  926. $this->query("commit");
  927. $this->trans_status = false;
  928. }
  929. }
  930. /**
  931. *回滚事务
  932. * @param boolean $pInTrans
  933. */
  934. function Rollback($pInTrans)
  935. {
  936. if ($pInTrans && $this->InTransaction()){
  937. $this->query("rollback");
  938. $this->trans_status = false;
  939. }
  940. }
  941. }
  942. ?>