DbMysqli.class.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2007 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. // $Id$
  12. /**
  13. +------------------------------------------------------------------------------
  14. * Mysqli数据库驱动类
  15. +------------------------------------------------------------------------------
  16. * @category Think
  17. * @package Think
  18. * @subpackage Db
  19. * @author liu21st <liu21st@gmail.com>
  20. * @version $Id$
  21. +------------------------------------------------------------------------------
  22. */
  23. class DbMysqli extends Db{
  24. /**
  25. +----------------------------------------------------------
  26. * 架构函数 读取数据库配置信息
  27. +----------------------------------------------------------
  28. * @access public
  29. +----------------------------------------------------------
  30. * @param array $config 数据库配置数组
  31. +----------------------------------------------------------
  32. */
  33. public function __construct($config=''){
  34. if ( !extension_loaded('mysqli') ) {
  35. throw_exception(L('_NOT_SUPPERT_').':mysqli');
  36. }
  37. if(!empty($config)) {
  38. $this->config = $config;
  39. }
  40. }
  41. /**
  42. +----------------------------------------------------------
  43. * 连接数据库方法
  44. +----------------------------------------------------------
  45. * @access public
  46. +----------------------------------------------------------
  47. * @throws ThinkExecption
  48. +----------------------------------------------------------
  49. */
  50. public function connect($config='',$linkNum=0) {
  51. if ( !isset($this->linkID[$linkNum]) ) {
  52. if(empty($config)) $config = $this->config;
  53. $this->linkID[$linkNum] = new mysqli($config['hostname'],$config['username'],$config['password'],$config['database'],$config['hostport']);
  54. if (mysqli_connect_errno()) throw_exception(mysqli_connect_error());
  55. $dbVersion = $this->linkID[$linkNum]->server_version;
  56. if ($dbVersion >= "4.1") {
  57. // 设置数据库编码 需要mysql 4.1.0以上支持
  58. $this->linkID[$linkNum]->query("SET NAMES '".C('DB_CHARSET')."'");
  59. }
  60. //设置 sql_model
  61. if($dbVersion >'5.0.1'){
  62. $this->linkID[$linkNum]->query("SET sql_mode=''");
  63. }
  64. // 标记连接成功
  65. $this->connected = true;
  66. //注销数据库安全信息
  67. if(1 != C('DB_DEPLOY_TYPE')) unset($this->config);
  68. }
  69. return $this->linkID[$linkNum];
  70. }
  71. /**
  72. +----------------------------------------------------------
  73. * 释放查询结果
  74. +----------------------------------------------------------
  75. * @access public
  76. +----------------------------------------------------------
  77. */
  78. public function free() {
  79. mysqli_free_result($this->queryID);
  80. $this->queryID = 0;
  81. }
  82. /**
  83. +----------------------------------------------------------
  84. * 执行查询 返回数据集
  85. +----------------------------------------------------------
  86. * @access public
  87. +----------------------------------------------------------
  88. * @param string $str sql指令
  89. +----------------------------------------------------------
  90. * @return mixed
  91. +----------------------------------------------------------
  92. * @throws ThinkExecption
  93. +----------------------------------------------------------
  94. */
  95. public function query($str) {
  96. $this->initConnect(false);
  97. if ( !$this->_linkID ) return false;
  98. $this->queryStr = $str;
  99. //释放前次的查询结果
  100. if ( $this->queryID ) $this->free();
  101. $this->Q(1);
  102. $this->queryID = $this->_linkID->query($str);
  103. $this->debug();
  104. if ( false === $this->queryID ) {
  105. $this->error();
  106. return false;
  107. } else {
  108. $this->numRows = $this->queryID->num_rows;
  109. $this->numCols = $this->queryID->field_count;
  110. return $this->getAll();
  111. }
  112. }
  113. /**
  114. +----------------------------------------------------------
  115. * 执行语句
  116. +----------------------------------------------------------
  117. * @access public
  118. +----------------------------------------------------------
  119. * @param string $str sql指令
  120. +----------------------------------------------------------
  121. * @return integer
  122. +----------------------------------------------------------
  123. * @throws ThinkExecption
  124. +----------------------------------------------------------
  125. */
  126. public function execute($str) {
  127. $this->initConnect(true);
  128. if ( !$this->_linkID ) return false;
  129. $this->queryStr = $str;
  130. //释放前次的查询结果
  131. if ( $this->queryID ) $this->free();
  132. $this->W(1);
  133. $result = $this->_linkID->query($str);
  134. $this->debug();
  135. if ( false === $result ) {
  136. $this->error();
  137. return false;
  138. } else {
  139. $this->numRows = $this->_linkID->affected_rows;
  140. $this->lastInsID = $this->_linkID->insert_id;
  141. return $this->numRows;
  142. }
  143. }
  144. /**
  145. +----------------------------------------------------------
  146. * 启动事务
  147. +----------------------------------------------------------
  148. * @access public
  149. +----------------------------------------------------------
  150. * @return void
  151. +----------------------------------------------------------
  152. * @throws ThinkExecption
  153. +----------------------------------------------------------
  154. */
  155. public function startTrans() {
  156. $this->initConnect(true);
  157. //数据rollback 支持
  158. if ($this->transTimes == 0) {
  159. $this->_linkID->autocommit(false);
  160. }
  161. $this->transTimes++;
  162. return ;
  163. }
  164. /**
  165. +----------------------------------------------------------
  166. * 用于非自动提交状态下面的查询提交
  167. +----------------------------------------------------------
  168. * @access public
  169. +----------------------------------------------------------
  170. * @return boolen
  171. +----------------------------------------------------------
  172. * @throws ThinkExecption
  173. +----------------------------------------------------------
  174. */
  175. public function commit()
  176. {
  177. if ($this->transTimes > 0) {
  178. $result = $this->_linkID->commit();
  179. $this->_linkID->autocommit( true);
  180. $this->transTimes = 0;
  181. if(!$result){
  182. throw_exception($this->error());
  183. }
  184. }
  185. return true;
  186. }
  187. /**
  188. +----------------------------------------------------------
  189. * 事务回滚
  190. +----------------------------------------------------------
  191. * @access public
  192. +----------------------------------------------------------
  193. * @return boolen
  194. +----------------------------------------------------------
  195. * @throws ThinkExecption
  196. +----------------------------------------------------------
  197. */
  198. public function rollback()
  199. {
  200. if ($this->transTimes > 0) {
  201. $result = $this->_linkID->rollback();
  202. $this->transTimes = 0;
  203. if(!$result){
  204. throw_exception($this->error());
  205. }
  206. }
  207. return true;
  208. }
  209. /**
  210. +----------------------------------------------------------
  211. * 获得所有的查询数据
  212. +----------------------------------------------------------
  213. * @access private
  214. +----------------------------------------------------------
  215. * @param string $sql sql语句
  216. +----------------------------------------------------------
  217. * @return array
  218. +----------------------------------------------------------
  219. */
  220. private function getAll() {
  221. //返回数据集
  222. $result = array();
  223. if($this->numRows>0) {
  224. //返回数据集
  225. for($i=0;$i<$this->numRows ;$i++ ){
  226. $result[$i] = $this->queryID->fetch_assoc();
  227. }
  228. $this->queryID->data_seek(0);
  229. }
  230. return $result;
  231. }
  232. /**
  233. +----------------------------------------------------------
  234. * 取得数据表的字段信息
  235. +----------------------------------------------------------
  236. * @access public
  237. +----------------------------------------------------------
  238. * @throws ThinkExecption
  239. +----------------------------------------------------------
  240. */
  241. function getFields($tableName) {
  242. $result = $this->query('SHOW COLUMNS FROM '.$tableName);
  243. $info = array();
  244. if($result) {
  245. foreach ($result as $key => $val) {
  246. $info[$val['Field']] = array(
  247. 'name' => $val['Field'],
  248. 'type' => $val['Type'],
  249. 'notnull' => (bool) ($val['Null'] === ''), // not null is empty, null is yes
  250. 'default' => $val['Default'],
  251. 'primary' => (strtolower($val['Key']) == 'pri'),
  252. 'autoinc' => (strtolower($val['Extra']) == 'auto_increment'),
  253. );
  254. }
  255. }
  256. return $info;
  257. }
  258. /**
  259. +----------------------------------------------------------
  260. * 取得数据表的字段信息
  261. +----------------------------------------------------------
  262. * @access public
  263. +----------------------------------------------------------
  264. * @throws ThinkExecption
  265. +----------------------------------------------------------
  266. */
  267. function getTables($dbName='') {
  268. $sql = !empty($dbName)?'SHOW TABLES FROM '.$dbName:'SHOW TABLES ';
  269. $result = $this->query($sql);
  270. $info = array();
  271. if($result) {
  272. foreach ($result as $key => $val) {
  273. $info[$key] = current($val);
  274. }
  275. }
  276. return $info;
  277. }
  278. /**
  279. +----------------------------------------------------------
  280. * 替换记录
  281. +----------------------------------------------------------
  282. * @access public
  283. +----------------------------------------------------------
  284. * @param mixed $data 数据
  285. * @param array $options 参数表达式
  286. +----------------------------------------------------------
  287. * @return false | integer
  288. +----------------------------------------------------------
  289. */
  290. public function replace($data,$options=array()) {
  291. foreach ($data as $key=>$val){
  292. $value = $this->parseValue($val);
  293. if(is_scalar($value)) { // 过滤非标量数据
  294. $values[] = $value;
  295. $fields[] = $this->addSpecialChar($key);
  296. }
  297. }
  298. $sql = 'REPLACE INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')';
  299. return $this->execute($sql);
  300. }
  301. /**
  302. +----------------------------------------------------------
  303. * 插入记录
  304. +----------------------------------------------------------
  305. * @access public
  306. +----------------------------------------------------------
  307. * @param mixed $datas 数据
  308. * @param array $options 参数表达式
  309. +----------------------------------------------------------
  310. * @return false | integer
  311. +----------------------------------------------------------
  312. */
  313. public function insertAll($datas,$options=array()) {
  314. if(!is_array($datas[0])) return false;
  315. $fields = array_keys($datas[0]);
  316. array_walk($fields, array($this, 'addSpecialChar'));
  317. $values = array();
  318. foreach ($datas as $data){
  319. $value = array();
  320. foreach ($data as $key=>$val){
  321. $val = $this->parseValue($val);
  322. if(is_scalar($val)) { // 过滤非标量数据
  323. $value[] = $val;
  324. }
  325. }
  326. $values[] = '('.implode(',', $value).')';
  327. }
  328. $sql = 'INSERT INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values);
  329. return $this->execute($sql);
  330. }
  331. /**
  332. +----------------------------------------------------------
  333. * 关闭数据库
  334. +----------------------------------------------------------
  335. * @static
  336. * @access public
  337. +----------------------------------------------------------
  338. * @throws ThinkExecption
  339. +----------------------------------------------------------
  340. */
  341. function close() {
  342. if (!empty($this->queryID))
  343. $this->queryID->free_result();
  344. if ($this->_linkID && !$this->_linkID->close()){
  345. throw_exception($this->error());
  346. }
  347. $this->_linkID = 0;
  348. }
  349. /**
  350. +----------------------------------------------------------
  351. * 数据库错误信息
  352. * 并显示当前的SQL语句
  353. +----------------------------------------------------------
  354. * @static
  355. * @access public
  356. +----------------------------------------------------------
  357. * @return string
  358. +----------------------------------------------------------
  359. */
  360. function error() {
  361. $this->error = $this->_linkID->error;
  362. if($this->debug && '' != $this->queryStr){
  363. $this->error .= "\n [ SQL语句 ] : ".$this->queryStr;
  364. }
  365. return $this->error;
  366. }
  367. /**
  368. +----------------------------------------------------------
  369. * SQL指令安全过滤
  370. +----------------------------------------------------------
  371. * @static
  372. * @access public
  373. +----------------------------------------------------------
  374. * @param string $str SQL指令
  375. +----------------------------------------------------------
  376. * @return string
  377. +----------------------------------------------------------
  378. */
  379. function escape_string($str) {
  380. if($this->_linkID) {
  381. return $this->_linkID->real_escape_string($str);
  382. }else{
  383. return addslashes($str);
  384. }
  385. }
  386. /**
  387. +----------------------------------------------------------
  388. * 析构方法
  389. +----------------------------------------------------------
  390. * @access public
  391. +----------------------------------------------------------
  392. */
  393. public function __destruct()
  394. {
  395. // 关闭连接
  396. $this->close();
  397. }
  398. }//类定义结束
  399. ?>