DbMysqli.class.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <?php
  2. // +--------------------------------------------------------------------------
  3. // | Senthot [ DEVELOPED BY ME ]
  4. // +--------------------------------------------------------------------------
  5. // | Copyright (c) 2007 http://www.senthot.com All rights reserved.
  6. // | License ( http://www.apache.org/licenses/LICENSE-2.0 )
  7. // | Author: ms134n ( [email protected] )
  8. // +--------------------------------------------------------------------------
  9. defined('SEN_PATH') or exit();
  10. /**
  11. * Mysqli database driver class
  12. * @category Sen
  13. * @package Sen
  14. * @subpackage Driver.Db
  15. * @author ms134n <[email protected]>
  16. */
  17. class DbMysqli extends Db{
  18. /**
  19. * Architecture function Read the database configuration information
  20. * @access public
  21. * @param array $config Database configuration array
  22. */
  23. public function __construct($config=''){
  24. if ( !extension_loaded('mysqli') ) {
  25. throw_exception(L('_NOT_SUPPERT_').':mysqli');
  26. }
  27. if(!empty($config)) {
  28. $this->config = $config;
  29. if(empty($this->config['params'])) {
  30. $this->config['params'] = '';
  31. }
  32. }
  33. }
  34. /**
  35. * Connection database method
  36. * @access public
  37. * @throws SenExecption
  38. */
  39. public function connect($config='',$linkNum=0) {
  40. if ( !isset($this->linkID[$linkNum]) ) {
  41. if(empty($config)) $config = $this->config;
  42. $this->linkID[$linkNum] = new mysqli($config['hostname'],$config['username'],$config['password'],$config['database'],$config['hostport']?intval($config['hostport']):3306);
  43. if (mysqli_connect_errno()) throw_exception(mysqli_connect_error());
  44. $dbVersion = $this->linkID[$linkNum]->server_version;
  45. // Set the database encoding
  46. $this->linkID[$linkNum]->query("SET NAMES '".C('DB_CHARSET')."'");
  47. //Setup sql_model
  48. if($dbVersion >'5.0.1'){
  49. $this->linkID[$linkNum]->query("SET sql_mode=''");
  50. }
  51. // Mark connection successful
  52. $this->connected = true;
  53. //Unregister database security information
  54. if(1 != C('DB_DEPLOY_TYPE')) unset($this->config);
  55. }
  56. return $this->linkID[$linkNum];
  57. }
  58. /**
  59. * Query results released
  60. * @access public
  61. */
  62. public function free() {
  63. $this->queryID->free_result();
  64. $this->queryID = null;
  65. }
  66. /**
  67. * Execute the query Returns a DataSet
  68. * @access public
  69. * @param string $str SQL commands
  70. * @return mixed
  71. */
  72. public function query($str) {
  73. $this->initConnect(false);
  74. if ( !$this->_linkID ) return false;
  75. $this->queryStr = $str;
  76. //Release the previous query results
  77. if ( $this->queryID ) $this->free();
  78. N('db_query',1);
  79. // Record the start time
  80. G('queryStartTime');
  81. $this->queryID = $this->_linkID->query($str);
  82. // Stored procedures improve
  83. if( $this->_linkID->more_results() ){
  84. while (($res = $this->_linkID->next_result()) != NULL) {
  85. $res->free_result();
  86. }
  87. }
  88. $this->debug();
  89. if ( false === $this->queryID ) {
  90. $this->error();
  91. return false;
  92. } else {
  93. $this->numRows = $this->queryID->num_rows;
  94. $this->numCols = $this->queryID->field_count;
  95. return $this->getAll();
  96. }
  97. }
  98. /**
  99. * Execute the statement
  100. * @access public
  101. * @param string $str SQL commands
  102. * @return integer
  103. */
  104. public function execute($str) {
  105. $this->initConnect(true);
  106. if ( !$this->_linkID ) return false;
  107. $this->queryStr = $str;
  108. //Release the previous query results
  109. if ( $this->queryID ) $this->free();
  110. N('db_write',1);
  111. // Record the start time
  112. G('queryStartTime');
  113. $result = $this->_linkID->query($str);
  114. $this->debug();
  115. if ( false === $result ) {
  116. $this->error();
  117. return false;
  118. } else {
  119. $this->numRows = $this->_linkID->affected_rows;
  120. $this->lastInsID = $this->_linkID->insert_id;
  121. return $this->numRows;
  122. }
  123. }
  124. /**
  125. * Start transaction
  126. * @access public
  127. * @return void
  128. */
  129. public function startTrans() {
  130. $this->initConnect(true);
  131. //Data rollback Support
  132. if ($this->transTimes == 0) {
  133. $this->_linkID->autocommit(false);
  134. }
  135. $this->transTimes++;
  136. return ;
  137. }
  138. /**
  139. * For non-autocommit State the following query submission
  140. * @access public
  141. * @return boolen
  142. */
  143. public function commit() {
  144. if ($this->transTimes > 0) {
  145. $result = $this->_linkID->commit();
  146. $this->_linkID->autocommit( true);
  147. $this->transTimes = 0;
  148. if(!$result){
  149. $this->error();
  150. return false;
  151. }
  152. }
  153. return true;
  154. }
  155. /**
  156. * Transaction rollback
  157. * @access public
  158. * @return boolen
  159. */
  160. public function rollback() {
  161. if ($this->transTimes > 0) {
  162. $result = $this->_linkID->rollback();
  163. $this->transTimes = 0;
  164. if(!$result){
  165. $this->error();
  166. return false;
  167. }
  168. }
  169. return true;
  170. }
  171. /**
  172. * Get all the query data
  173. * @access private
  174. * @param string $sql SQL statement
  175. * @return array
  176. */
  177. private function getAll() {
  178. //Returns a DataSet
  179. $result = array();
  180. if($this->numRows>0) {
  181. //Returns a DataSet
  182. for($i=0;$i<$this->numRows ;$i++ ){
  183. $result[$i] = $this->queryID->fetch_assoc();
  184. }
  185. $this->queryID->data_seek(0);
  186. }
  187. return $result;
  188. }
  189. /**
  190. * Information obtained field data sheet
  191. * @access public
  192. * @return array
  193. */
  194. public function getFields($tableName) {
  195. $result = $this->query('SHOW COLUMNS FROM '.$this->parseKey($tableName));
  196. $info = array();
  197. if($result) {
  198. foreach ($result as $key => $val) {
  199. $info[$val['Field']] = array(
  200. 'name' => $val['Field'],
  201. 'type' => $val['Type'],
  202. 'notnull' => (bool) ($val['Null'] === ''), // not null is empty, null is yes
  203. 'default' => $val['Default'],
  204. 'primary' => (strtolower($val['Key']) == 'pri'),
  205. 'autoinc' => (strtolower($val['Extra']) == 'auto_increment'),
  206. );
  207. }
  208. }
  209. return $info;
  210. }
  211. /**
  212. * Information obtained field data sheet
  213. * @access public
  214. * @return array
  215. */
  216. public function getTables($dbName='') {
  217. $sql = !empty($dbName)?'SHOW TABLES FROM '.$dbName:'SHOW TABLES ';
  218. $result = $this->query($sql);
  219. $info = array();
  220. if($result) {
  221. foreach ($result as $key => $val) {
  222. $info[$key] = current($val);
  223. }
  224. }
  225. return $info;
  226. }
  227. /**
  228. * Replace Record
  229. * @access public
  230. * @param mixed $data Data
  231. * @param array $options Parameter expression
  232. * @return false | integer
  233. */
  234. public function replace($data,$options=array()) {
  235. foreach ($data as $key=>$val){
  236. $value = $this->parseValue($val);
  237. if(is_scalar($value)) { // Filtering non-scalar data
  238. $values[] = $value;
  239. $fields[] = $this->parseKey($key);
  240. }
  241. }
  242. $sql = 'REPLACE INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')';
  243. return $this->execute($sql);
  244. }
  245. /**
  246. * Insert records
  247. * @access public
  248. * @param mixed $datas Data
  249. * @param array $options Parameter expression
  250. * @param boolean $replace Whether or replace
  251. * @return false | integer
  252. */
  253. public function insertAll($datas,$options=array(),$replace=false) {
  254. if(!is_array($datas[0])) return false;
  255. $fields = array_keys($datas[0]);
  256. array_walk($fields, array($this, 'parseKey'));
  257. $values = array();
  258. foreach ($datas as $data){
  259. $value = array();
  260. foreach ($data as $key=>$val){
  261. $val = $this->parseValue($val);
  262. if(is_scalar($val)) { // Filtering non-scalar data
  263. $value[] = $val;
  264. }
  265. }
  266. $values[] = '('.implode(',', $value).')';
  267. }
  268. $sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values);
  269. return $this->execute($sql);
  270. }
  271. /**
  272. * Close the database
  273. * @access public
  274. * @return volid
  275. */
  276. public function close() {
  277. if ($this->_linkID){
  278. $this->_linkID->close();
  279. }
  280. $this->_linkID = null;
  281. }
  282. /**
  283. * Database Error Messages
  284. * And displays the current SQL statement
  285. * @static
  286. * @access public
  287. * @return string
  288. */
  289. public function error() {
  290. $this->error = $this->_linkID->error;
  291. if('' != $this->queryStr){
  292. $this->error .= "\n [ SQL statement ] : ".$this->queryStr;
  293. }
  294. trace($this->error,'','ERR');
  295. return $this->error;
  296. }
  297. /**
  298. * SQL commands security filtering
  299. * @static
  300. * @access public
  301. * @param string $str SQL commands
  302. * @return string
  303. */
  304. public function escapeString($str) {
  305. if($this->_linkID) {
  306. return $this->_linkID->real_escape_string($str);
  307. }else{
  308. return addslashes($str);
  309. }
  310. }
  311. /**
  312. * Field and table names added processing`
  313. * @access protected
  314. * @param string $key
  315. * @return string
  316. */
  317. protected function parseKey(&$key) {
  318. $key = trim($key);
  319. if(!preg_match('/[,\'\"\*\(\)`.\s]/',$key)) {
  320. $key = '`'.$key.'`';
  321. }
  322. return $key;
  323. }
  324. }