Guest User

Untitled

a guest
Dec 18th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.58 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * Database driver
  5. *
  6. * @var string
  7. */
  8. public $dbdriver = 'mysqli';
  9.  
  10. /**
  11. * Compression flag
  12. *
  13. * @var bool
  14. */
  15. public $compress = FALSE;
  16.  
  17. /**
  18. * DELETE hack flag
  19. *
  20. * Whether to use the MySQL "delete hack" which allows the number
  21. * of affected rows to be shown. Uses a preg_replace when enabled,
  22. * adding a bit more processing to all queries.
  23. *
  24. * @var bool
  25. */
  26. public $delete_hack = TRUE;
  27.  
  28. /**
  29. * Strict ON flag
  30. *
  31. * Whether we're running in strict SQL mode.
  32. *
  33. * @var bool
  34. */
  35. public $stricton;
  36.  
  37. // --------------------------------------------------------------------
  38.  
  39. /**
  40. * Identifier escape character
  41. *
  42. * @var string
  43. */
  44. protected $_escape_char = '`';
  45.  
  46. // --------------------------------------------------------------------
  47.  
  48. /**
  49. * MySQLi object
  50. *
  51. * Has to be preserved without being assigned to $conn_id.
  52. *
  53. * @var MySQLi
  54. */
  55. protected $_mysqli;
  56.  
  57. // --------------------------------------------------------------------
  58.  
  59. /**
  60. * Database connection
  61. *
  62. * @param bool $persistent
  63. * @return object
  64. */
  65. public function db_connect($persistent = FALSE)
  66. {
  67. // Do we have a socket path?
  68. if ($this->hostname[0] === '/')
  69. {
  70. $hostname = NULL;
  71. $port = NULL;
  72. $socket = $this->hostname;
  73. }
  74. else
  75. {
  76. $hostname = ($persistent === TRUE)
  77. ? 'p:'.$this->hostname : $this->hostname;
  78. $port = empty($this->port) ? NULL : $this->port;
  79. $socket = NULL;
  80. }
  81.  
  82. $client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0;
  83. $this->_mysqli = mysqli_init();
  84.  
  85. $this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10);
  86.  
  87. if (isset($this->stricton))
  88. {
  89. if ($this->stricton)
  90. {
  91. $this->_mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")');
  92. }
  93. else
  94. {
  95. $this->_mysqli->options(MYSQLI_INIT_COMMAND,
  96. 'SET SESSION sql_mode =
  97. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  98. @@sql_mode,
  99. "STRICT_ALL_TABLES,", ""),
  100. ",STRICT_ALL_TABLES", ""),
  101. "STRICT_ALL_TABLES", ""),
  102. "STRICT_TRANS_TABLES,", ""),
  103. ",STRICT_TRANS_TABLES", ""),
  104. "STRICT_TRANS_TABLES", "")'
  105. );
  106. }
  107. }
  108.  
  109. if (is_array($this->encrypt))
  110. {
  111. $ssl = array();
  112. empty($this->encrypt['ssl_key']) OR $ssl['key'] = $this->encrypt['ssl_key'];
  113. empty($this->encrypt['ssl_cert']) OR $ssl['cert'] = $this->encrypt['ssl_cert'];
  114. empty($this->encrypt['ssl_ca']) OR $ssl['ca'] = $this->encrypt['ssl_ca'];
  115. empty($this->encrypt['ssl_capath']) OR $ssl['capath'] = $this->encrypt['ssl_capath'];
  116. empty($this->encrypt['ssl_cipher']) OR $ssl['cipher'] = $this->encrypt['ssl_cipher'];
  117.  
  118. if ( ! empty($ssl))
  119. {
  120. if (isset($this->encrypt['ssl_verify']))
  121. {
  122. if ($this->encrypt['ssl_verify'])
  123. {
  124. defined('MYSQLI_OPT_SSL_VERIFY_SERVER_CERT') && $this->_mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, TRUE);
  125. }
  126. // Apparently (when it exists), setting MYSQLI_OPT_SSL_VERIFY_SERVER_CERT
  127. // to FALSE didn't do anything, so PHP 5.6.16 introduced yet another
  128. // constant ...
  129. //
  130. // https://secure.php.net/ChangeLog-5.php#5.6.16
  131. // https://bugs.php.net/bug.php?id=68344
  132. elseif (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT'))
  133. {
  134. $client_flags |= MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
  135. }
  136. }
  137.  
  138. $client_flags |= MYSQLI_CLIENT_SSL;
  139. $this->_mysqli->ssl_set(
  140. isset($ssl['key']) ? $ssl['key'] : NULL,
  141. isset($ssl['cert']) ? $ssl['cert'] : NULL,
  142. isset($ssl['ca']) ? $ssl['ca'] : NULL,
  143. isset($ssl['capath']) ? $ssl['capath'] : NULL,
  144. isset($ssl['cipher']) ? $ssl['cipher'] : NULL
  145. );
  146. }
  147. }
  148.  
  149. if ($this->_mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags))
  150. {
  151. // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails
  152. if (
  153. ($client_flags & MYSQLI_CLIENT_SSL)
  154. && version_compare($this->_mysqli->client_info, '5.7.3', '<=')
  155. && empty($this->_mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_object()->Value)
  156. )
  157. {
  158. $this->_mysqli->close();
  159. $message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!';
  160. log_message('error', $message);
  161. return ($this->db_debug) ? $this->display_error($message, '', TRUE) : FALSE;
  162. }
  163.  
  164. return $this->_mysqli;
  165. }
  166.  
  167. return FALSE;
  168. }
  169.  
  170. // --------------------------------------------------------------------
  171.  
  172. /**
  173. * Reconnect
  174. *
  175. * Keep / reestablish the db connection if no queries have been
  176. * sent for a length of time exceeding the server's idle timeout
  177. *
  178. * @return void
  179. */
  180. public function reconnect()
  181. {
  182. if ($this->conn_id !== FALSE && $this->conn_id->ping() === FALSE)
  183. {
  184. $this->conn_id = FALSE;
  185. }
  186. }
  187.  
  188. // --------------------------------------------------------------------
  189.  
  190. /**
  191. * Select the database
  192. *
  193. * @param string $database
  194. * @return bool
  195. */
  196. public function db_select($database = '')
  197. {
  198. if ($database === '')
  199. {
  200. $database = $this->database;
  201. }
  202.  
  203. if ($this->conn_id->select_db($database))
  204. {
  205. $this->database = $database;
  206. $this->data_cache = array();
  207. return TRUE;
  208. }
  209.  
  210. return FALSE;
  211. }
  212.  
  213. // --------------------------------------------------------------------
  214.  
  215. /**
  216. * Set client character set
  217. *
  218. * @param string $charset
  219. * @return bool
  220. */
  221. protected function _db_set_charset($charset)
  222. {
  223. return $this->conn_id->set_charset($charset);
  224. }
  225.  
  226. // --------------------------------------------------------------------
  227.  
  228. /**
  229. * Database version number
  230. *
  231. * @return string
  232. */
  233. public function version()
  234. {
  235. if (isset($this->data_cache['version']))
  236. {
  237. return $this->data_cache['version'];
  238. }
  239.  
  240. return $this->data_cache['version'] = $this->conn_id->server_info;
  241. }
  242.  
  243. // --------------------------------------------------------------------
  244.  
  245. /**
  246. * Execute the query
  247. *
  248. * @param string $sql an SQL query
  249. * @return mixed
  250. */
  251. protected function _execute($sql)
  252. {
  253. return $this->conn_id->query($this->_prep_query($sql));
  254. }
  255.  
  256. // --------------------------------------------------------------------
  257.  
  258. /**
  259. * Prep the query
  260. *
  261. * If needed, each database adapter can prep the query string
  262. *
  263. * @param string $sql an SQL query
  264. * @return string
  265. */
  266. protected function _prep_query($sql)
  267. {
  268. // mysqli_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack
  269. // modifies the query so that it a proper number of affected rows is returned.
  270. if ($this->delete_hack === TRUE && preg_match('/^s*DELETEs+FROMs+(S+)s*$/i', $sql))
  271. {
  272. return trim($sql).' WHERE 1=1';
  273. }
  274.  
  275. return $sql;
  276. }
  277.  
  278. // --------------------------------------------------------------------
  279.  
  280. /**
  281. * Begin Transaction
  282. *
  283. * @return bool
  284. */
  285. protected function _trans_begin()
  286. {
  287. $this->conn_id->autocommit(FALSE);
  288. return is_php('5.5')
  289. ? $this->conn_id->begin_transaction()
  290. : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
  291. }
  292.  
  293. // --------------------------------------------------------------------
  294.  
  295. /**
  296. * Commit Transaction
  297. *
  298. * @return bool
  299. */
  300. protected function _trans_commit()
  301. {
  302. if ($this->conn_id->commit())
  303. {
  304. $this->conn_id->autocommit(TRUE);
  305. return TRUE;
  306. }
  307.  
  308. return FALSE;
  309. }
  310.  
  311. // --------------------------------------------------------------------
  312.  
  313. /**
  314. * Rollback Transaction
  315. *
  316. * @return bool
  317. */
  318. protected function _trans_rollback()
  319. {
  320. if ($this->conn_id->rollback())
  321. {
  322. $this->conn_id->autocommit(TRUE);
  323. return TRUE;
  324. }
  325.  
  326. return FALSE;
  327. }
  328.  
  329. // --------------------------------------------------------------------
  330.  
  331. /**
  332. * Platform-dependent string escape
  333. *
  334. * @param string
  335. * @return string
  336. */
  337. protected function _escape_str($str)
  338. {
  339. return $this->conn_id->real_escape_string($str);
  340. }
  341.  
  342. // --------------------------------------------------------------------
  343.  
  344. /**
  345. * Affected Rows
  346. *
  347. * @return int
  348. */
  349. public function affected_rows()
  350. {
  351. return $this->conn_id->affected_rows;
  352. }
  353.  
  354. // --------------------------------------------------------------------
  355.  
  356. /**
  357. * Insert ID
  358. *
  359. * @return int
  360. */
  361. public function insert_id()
  362. {
  363. return $this->conn_id->insert_id;
  364. }
  365.  
  366. // --------------------------------------------------------------------
  367.  
  368. /**
  369. * List table query
  370. *
  371. * Generates a platform-specific query string so that the table names can be fetched
  372. *
  373. * @param bool $prefix_limit
  374. * @return string
  375. */
  376. protected function _list_tables($prefix_limit = FALSE)
  377. {
  378. $sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database);
  379.  
  380. if ($prefix_limit !== FALSE && $this->dbprefix !== '')
  381. {
  382. return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'";
  383. }
  384.  
  385. return $sql;
  386. }
  387.  
  388. // --------------------------------------------------------------------
  389.  
  390. /**
  391. * Show column query
  392. *
  393. * Generates a platform-specific query string so that the column names can be fetched
  394. *
  395. * @param string $table
  396. * @return string
  397. */
  398. protected function _list_columns($table = '')
  399. {
  400. return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE);
  401. }
  402.  
  403. // --------------------------------------------------------------------
  404.  
  405. /**
  406. * Returns an object with field data
  407. *
  408. * @param string $table
  409. * @return array
  410. */
  411. public function field_data($table)
  412. {
  413. if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE)
  414. {
  415. return FALSE;
  416. }
  417. $query = $query->result_object();
  418.  
  419. $retval = array();
  420. for ($i = 0, $c = count($query); $i < $c; $i++)
  421. {
  422. $retval[$i] = new stdClass();
  423. $retval[$i]->name = $query[$i]->Field;
  424.  
  425. sscanf($query[$i]->Type, '%[a-z](%d)',
  426. $retval[$i]->type,
  427. $retval[$i]->max_length
  428. );
  429.  
  430. $retval[$i]->default = $query[$i]->Default;
  431. $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI');
  432. }
  433.  
  434. return $retval;
  435. }
  436.  
  437. // --------------------------------------------------------------------
  438.  
  439. /**
  440. * Error
  441. *
  442. * Returns an array containing code and message of the last
  443. * database error that has occurred.
  444. *
  445. * @return array
  446. */
  447. public function error()
  448. {
  449. if ( ! empty($this->_mysqli->connect_errno))
  450. {
  451. return array(
  452. 'code' => $this->_mysqli->connect_errno,
  453. 'message' => $this->_mysqli->connect_error
  454. );
  455. }
  456.  
  457. return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error);
  458. }
  459.  
  460. // --------------------------------------------------------------------
  461.  
  462. /**
  463. * FROM tables
  464. *
  465. * Groups tables in FROM clauses if needed, so there is no confusion
  466. * about operator precedence.
  467. *
  468. * @return string
  469. */
  470. protected function _from_tables()
  471. {
  472. if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
  473. {
  474. return '('.implode(', ', $this->qb_from).')';
  475. }
  476.  
  477. return implode(', ', $this->qb_from);
  478. }
  479.  
  480. // --------------------------------------------------------------------
  481.  
  482. /**
  483. * Close DB Connection
  484. *
  485. * @return void
  486. */
  487. protected function _close()
  488. {
  489. $this->conn_id->close();
  490. }
Add Comment
Please, Sign In to add comment