db.class.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. <?php
  2. /**
  3. * [WeEngine System] Copyright (c) 2014 WE7.CC
  4. * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
  5. */
  6. defined('IN_IA') or exit('Access Denied');
  7. define('PDO_DEBUG', true);
  8. class DB {
  9. protected $pdo;
  10. protected $cfg;
  11. protected $tablepre;
  12. protected $result;
  13. protected $statement;
  14. protected $errors = array();
  15. protected $link = array();
  16. public function getPDO() {
  17. return $this->pdo;
  18. }
  19. public function __construct($name = 'master') {
  20. global $_W;
  21. $this->cfg = $_W['config']['db'];
  22. unset($_W['config']['db']);
  23. $_W['config']['db']['tablepre'] = $this->cfg['tablepre'];
  24. $_W['config']['db']['slave_status'] = $this->cfg['slave_status'];
  25. $this->connect($name);
  26. }
  27. public function connect($name = 'master') {
  28. if(is_array($name)) {
  29. $cfg = $name;
  30. } else {
  31. $cfg = $this->cfg[$name];
  32. }
  33. $this->tablepre = $cfg['tablepre'];
  34. if(empty($cfg)) {
  35. exit("The master database is not found, Please checking 'data/config.php'");
  36. }
  37. $dsn = "mysql:dbname={$cfg['database']};host={$cfg['host']};port={$cfg['port']};charset={$cfg['charset']}";
  38. $dbclass = '';
  39. $options = array();
  40. if (class_exists('PDO')) {
  41. if (extension_loaded("pdo_mysql") && in_array('mysql', PDO::getAvailableDrivers())) {
  42. $dbclass = 'PDO';
  43. $options = array(PDO::ATTR_PERSISTENT => $cfg['pconnect']);
  44. } else {
  45. if(!class_exists('_PDO')) {
  46. load()->library('pdo');
  47. }
  48. $dbclass = '_PDO';
  49. }
  50. } else {
  51. load()->library('pdo');
  52. $dbclass = 'PDO';
  53. }
  54. $pdo = new $dbclass($dsn, $cfg['username'], $cfg['password'], $options);
  55. $this->pdo = $pdo;
  56. $sql = "SET NAMES '{$cfg['charset']}';";
  57. $this->pdo->exec($sql);
  58. $this->pdo->exec("SET sql_mode='';");
  59. if ($cfg['username'] == 'root') {
  60. $this->pdo->exec("SET GLOBAL max_allowed_packet = 2*1024*1024*10;");
  61. }
  62. if(is_string($name)) {
  63. $this->link[$name] = $this->pdo;
  64. }
  65. $this->logging($sql);
  66. }
  67. public function prepare($sql) {
  68. $sqlsafe = SqlPaser::checkquery($sql);
  69. if (is_error($sqlsafe)) {
  70. trigger_error($sqlsafe['message'], E_USER_ERROR);
  71. return false;
  72. }
  73. if ($GLOBALS['_W']['config']['setting']['development'] == 3) {
  74. if ($GLOBALS['error_handler'] instanceof Raven_ErrorHandler) {
  75. $GLOBALS['error_handler']->handleError(E_USER_ERROR, $sql);
  76. }
  77. }
  78. $statement = $this->pdo->prepare($sql);
  79. return $statement;
  80. }
  81. public function query($sql, $params = array()) {
  82. $sqlsafe = SqlPaser::checkquery($sql);
  83. if (is_error($sqlsafe)) {
  84. trigger_error($sqlsafe['message'], E_USER_ERROR);
  85. return false;
  86. }
  87. $starttime = microtime(true);
  88. if (empty($params)) {
  89. $result = $this->pdo->exec($sql);
  90. $this->logging($sql, array(), $this->pdo->errorInfo());
  91. return $result;
  92. }
  93. $statement = $this->prepare($sql);
  94. $result = $statement->execute($params);
  95. $this->logging($sql, $params, $statement->errorInfo());
  96. $endtime = microtime(true);
  97. $this->performance($sql, $endtime - $starttime);
  98. if (!$result) {
  99. return false;
  100. } else {
  101. return $statement->rowCount();
  102. }
  103. }
  104. public function fetchcolumn($sql, $params = array(), $column = 0) {
  105. $starttime = microtime();
  106. $statement = $this->prepare($sql);
  107. $result = $statement->execute($params);
  108. $this->logging($sql, $params, $statement->errorInfo());
  109. $endtime = microtime();
  110. $this->performance($sql, $endtime - $starttime);
  111. if (!$result) {
  112. return false;
  113. } else {
  114. $data = $statement->fetchColumn($column);
  115. return $data;
  116. }
  117. }
  118. public function fetch($sql, $params = array()) {
  119. $starttime = microtime();
  120. $statement = $this->prepare($sql);
  121. $result = $statement->execute($params);
  122. $this->logging($sql, $params, $statement->errorInfo());
  123. $endtime = microtime();
  124. $this->performance($sql, $endtime - $starttime);
  125. if (!$result) {
  126. return false;
  127. } else {
  128. set_time_limit(0);
  129. $data = $statement->fetch(pdo::FETCH_ASSOC);
  130. return $data;
  131. }
  132. }
  133. public function fetchall($sql, $params = array(), $keyfield = '') {
  134. $starttime = microtime();
  135. $statement = $this->prepare($sql);
  136. $result = $statement->execute($params);
  137. $this->logging($sql, $params, $statement->errorInfo());
  138. $endtime = microtime();
  139. $this->performance($sql, $endtime - $starttime);
  140. if (!$result) {
  141. return false;
  142. } else {
  143. if (empty($keyfield)) {
  144. $result = $statement->fetchAll(pdo::FETCH_ASSOC);
  145. } else {
  146. $temp = $statement->fetchAll(pdo::FETCH_ASSOC);
  147. $result = array();
  148. if (!empty($temp)) {
  149. foreach ($temp as $key => &$row) {
  150. if (isset($row[$keyfield])) {
  151. $result[$row[$keyfield]] = $row;
  152. } else {
  153. $result[] = $row;
  154. }
  155. }
  156. }
  157. }
  158. return $result;
  159. }
  160. }
  161. public function get($tablename, $params = array(), $fields = array(), $orderby = array()) {
  162. $select = SqlPaser::parseSelect($fields);
  163. $condition = SqlPaser::parseParameter($params, 'AND');
  164. $orderbysql = SqlPaser::parseOrderby($orderby);
  165. $sql = "{$select} FROM " . $this->tablename($tablename) . (!empty($condition['fields']) ? " WHERE {$condition['fields']}" : '') . " $orderbysql LIMIT 1";
  166. return $this->fetch($sql, $condition['params']);
  167. }
  168. public function getall($tablename, $params = array(), $fields = array(), $keyfield = '', $orderby = array(), $limit = array()) {
  169. $select = SqlPaser::parseSelect($fields);
  170. $condition = SqlPaser::parseParameter($params, 'AND');
  171. $limitsql = SqlPaser::parseLimit($limit);
  172. $orderbysql = SqlPaser::parseOrderby($orderby);
  173. $sql = "{$select} FROM " .$this->tablename($tablename) . (!empty($condition['fields']) ? " WHERE {$condition['fields']}" : '') . $orderbysql . $limitsql;
  174. return $this->fetchall($sql, $condition['params'], $keyfield);
  175. }
  176. public function getslice($tablename, $params = array(), $limit = array(), &$total = null, $fields = array(), $keyfield = '', $orderby = array()) {
  177. $select = SqlPaser::parseSelect($fields);
  178. $condition = SqlPaser::parseParameter($params, 'AND');
  179. $limitsql = SqlPaser::parseLimit($limit);
  180. if (!empty($orderby)) {
  181. if (is_array($orderby)) {
  182. $orderbysql = implode(',', $orderby);
  183. } else {
  184. $orderbysql = $orderby;
  185. }
  186. }
  187. $sql = "{$select} FROM " . $this->tablename($tablename) . (!empty($condition['fields']) ? " WHERE {$condition['fields']}" : '') . (!empty($orderbysql) ? " ORDER BY $orderbysql " : '') . $limitsql;
  188. $total = pdo_fetchcolumn("SELECT COUNT(*) FROM " . tablename($tablename) . (!empty($condition['fields']) ? " WHERE {$condition['fields']}" : ''), $condition['params']);
  189. return $this->fetchall($sql, $condition['params'], $keyfield);
  190. }
  191. public function getcolumn($tablename, $params = array(), $field = '') {
  192. $result = $this->get($tablename, $params, $field);
  193. if (!empty($result)) {
  194. if (strexists($field, '(')) {
  195. return array_shift($result);
  196. } else {
  197. return $result[$field];
  198. }
  199. } else {
  200. return false;
  201. }
  202. }
  203. public function update($table, $data = array(), $params = array(), $glue = 'AND') {
  204. $fields = SqlPaser::parseParameter($data, ',');
  205. $condition = SqlPaser::parseParameter($params, $glue);
  206. $params = array_merge($fields['params'], $condition['params']);
  207. $sql = "UPDATE " . $this->tablename($table) . " SET {$fields['fields']}";
  208. $sql .= $condition['fields'] ? ' WHERE '.$condition['fields'] : '';
  209. return $this->query($sql, $params);
  210. }
  211. public function insert($table, $data = array(), $replace = FALSE) {
  212. $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';
  213. $condition = SqlPaser::parseParameter($data, ',');
  214. return $this->query("$cmd " . $this->tablename($table) . " SET {$condition['fields']}", $condition['params']);
  215. }
  216. public function insertid() {
  217. return $this->pdo->lastInsertId();
  218. }
  219. public function delete($table, $params = array(), $glue = 'AND') {
  220. $condition = SqlPaser::parseParameter($params, $glue);
  221. $sql = "DELETE FROM " . $this->tablename($table);
  222. $sql .= $condition['fields'] ? ' WHERE '.$condition['fields'] : '';
  223. return $this->query($sql, $condition['params']);
  224. }
  225. public function exists($tablename, $params = array()) {
  226. $row = $this->get($tablename, $params);
  227. if (empty($row) || !is_array($row) || count($row) == 0) {
  228. return false;
  229. } else {
  230. return true;
  231. }
  232. }
  233. public function count($tablename, $params = array(), $cachetime = 30) {
  234. $total = pdo_getcolumn($tablename, $params, 'count(*)');
  235. return intval($total);
  236. }
  237. public function begin() {
  238. $this->pdo->beginTransaction();
  239. }
  240. public function commit() {
  241. $this->pdo->commit();
  242. }
  243. public function rollback() {
  244. $this->pdo->rollBack();
  245. }
  246. public function run($sql, $stuff = 'ims_') {
  247. if(!isset($sql) || empty($sql)) return;
  248. $sql = str_replace("\r", "\n", str_replace(' ' . $stuff, ' ' . $this->tablepre, $sql));
  249. $sql = str_replace("\r", "\n", str_replace(' `' . $stuff, ' `' . $this->tablepre, $sql));
  250. $ret = array();
  251. $num = 0;
  252. $sql = preg_replace("/\;[ \f\t\v]+/", ';', $sql);
  253. foreach(explode(";\n", trim($sql)) as $query) {
  254. $ret[$num] = '';
  255. $queries = explode("\n", trim($query));
  256. foreach($queries as $query) {
  257. $ret[$num] .= (isset($query[0]) && $query[0] == '#') || (isset($query[1]) && isset($query[1]) && $query[0].$query[1] == '--') ? '' : $query;
  258. }
  259. $num++;
  260. }
  261. unset($sql);
  262. foreach($ret as $query) {
  263. $query = trim($query);
  264. if($query) {
  265. $this->query($query, array());
  266. }
  267. }
  268. return true;
  269. }
  270. public function fieldexists($tablename, $fieldname) {
  271. $isexists = $this->fetch("DESCRIBE " . $this->tablename($tablename) . " `{$fieldname}`", array());
  272. return !empty($isexists) ? true : false;
  273. }
  274. public function fieldmatch($tablename, $fieldname, $datatype = '', $length = '') {
  275. $datatype = strtolower($datatype);
  276. $field_info = $this->fetch("DESCRIBE " . $this->tablename($tablename) . " `{$fieldname}`", array());
  277. if (empty($field_info)) {
  278. return false;
  279. }
  280. if (!empty($datatype)) {
  281. $find = strexists($field_info['Type'], '(');
  282. if (empty($find)) {
  283. $length = '';
  284. }
  285. if (!empty($length)) {
  286. $datatype .= ("({$length})");
  287. }
  288. return strpos($field_info['Type'], $datatype) === 0 ? true : -1;
  289. }
  290. return true;
  291. }
  292. public function indexexists($tablename, $indexname) {
  293. if (!empty($indexname)) {
  294. $indexs = $this->fetchall("SHOW INDEX FROM " . $this->tablename($tablename), array(), '');
  295. if (!empty($indexs) && is_array($indexs)) {
  296. foreach ($indexs as $row) {
  297. if ($row['Key_name'] == $indexname) {
  298. return true;
  299. }
  300. }
  301. }
  302. }
  303. return false;
  304. }
  305. public function tablename($table) {
  306. return (strpos($table, $this->tablepre) === 0 || strpos($table, 'ims_') === 0) ? $table : "`{$this->tablepre}{$table}`";
  307. }
  308. public function debug($output = true, $append = array()) {
  309. if(!empty($append)) {
  310. $output = false;
  311. array_push($this->errors, $append);
  312. }
  313. if($output) {
  314. print_r($this->errors);
  315. } else {
  316. if (!empty($append['error'][1])) {
  317. $traces = debug_backtrace();
  318. $ts = '';
  319. foreach($traces as $trace) {
  320. $trace['file'] = str_replace('\\', '/', $trace['file']);
  321. $trace['file'] = str_replace(IA_ROOT, '', $trace['file']);
  322. $ts .= "file: {$trace['file']}; line: {$trace['line']}; <br />";
  323. }
  324. $params = var_export($append['params'], true);
  325. trigger_error("SQL: <br/>{$append['sql']}<hr/>Params: <br/>{$params}<hr/>SQL Error: <br/>{$append['error'][2]}<hr/>Traces: <br/>{$ts}", E_USER_WARNING);
  326. }
  327. }
  328. return $this->errors;
  329. }
  330. private function logging($sql, $params = array(), $message = '') {
  331. if(PDO_DEBUG) {
  332. $info = array();
  333. $info['sql'] = $sql;
  334. $info['params'] = $params;
  335. $info['error'] = empty($message) ? $this->pdo->errorInfo() : $message;
  336. $this->debug(false, $info);
  337. }
  338. return true;
  339. }
  340. public function tableexists($table) {
  341. if(!empty($table)) {
  342. $data = $this->fetch("SHOW TABLES LIKE '{$this->tablepre}{$table}'", array());
  343. if(!empty($data)) {
  344. $data = array_values($data);
  345. $tablename = $this->tablepre . $table;
  346. if(in_array($tablename, $data)) {
  347. return true;
  348. } else {
  349. return false;
  350. }
  351. } else {
  352. return false;
  353. }
  354. } else {
  355. return false;
  356. }
  357. }
  358. private function performance($sql, $runtime = 0) {
  359. global $_W;
  360. if ($runtime == 0) {
  361. return false;
  362. }
  363. if (strexists($sql, 'core_performance')) {
  364. return false;
  365. }
  366. if (empty($_W['config']['setting']['maxtimesql'])) {
  367. $_W['config']['setting']['maxtimesql'] = 5;
  368. }
  369. if ($runtime > $_W['config']['setting']['maxtimesql']) {
  370. $sqldata = array(
  371. 'type' => '2',
  372. 'runtime' => $runtime,
  373. 'runurl' => 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'],
  374. 'runsql' => $sql,
  375. 'createtime' => time()
  376. );
  377. $this->insert('core_performance', $sqldata);
  378. }
  379. return true;
  380. }
  381. }
  382. class SqlPaser {
  383. private static $checkcmd = array('SELECT', 'UPDATE', 'INSERT', 'REPLAC', 'DELETE');
  384. private static $disable = array(
  385. 'function' => array('load_file', 'floor', 'hex', 'substring', 'if', 'ord', 'char', 'benchmark', 'reverse', 'strcmp', 'datadir', 'updatexml', 'extractvalue', 'name_const', 'multipoint', 'database', 'user'),
  386. 'action' => array('@', 'intooutfile', 'intodumpfile', 'unionselect', 'uniondistinct', 'information_schema', 'current_user', 'current_date'),
  387. 'note' => array('/*','*/','#','--'),
  388. );
  389. public static function checkquery($sql) {
  390. $cmd = strtoupper(substr(trim($sql), 0, 6));
  391. if (in_array($cmd, self::$checkcmd)) {
  392. $mark = $clean = '';
  393. $sql = str_replace(array('\\\\', '\\\'', '\\"', '\'\''), '', $sql);
  394. if (strpos($sql, '/') === false && strpos($sql, '#') === false && strpos($sql, '-- ') === false && strpos($sql, '@') === false && strpos($sql, '`') === false) {
  395. $cleansql = preg_replace("/'(.+?)'/s", '', $sql);
  396. } else {
  397. $cleansql = self::stripSafeChar($sql);
  398. }
  399. $cleansql = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is", "", strtolower($cleansql));
  400. if (is_array(self::$disable['function'])) {
  401. foreach (self::$disable['function'] as $fun) {
  402. if (strpos($cleansql, $fun . '(') !== false) {
  403. return error(1, 'SQL中包含禁用函数 - ' . $fun);
  404. }
  405. }
  406. }
  407. if (is_array(self::$disable['action'])) {
  408. foreach (self::$disable['action'] as $action) {
  409. if (strpos($cleansql, $action) !== false) {
  410. return error(2, 'SQL中包含禁用操作符 - ' . $action);
  411. }
  412. }
  413. }
  414. if (is_array(self::$disable['note'])) {
  415. foreach (self::$disable['note'] as $note) {
  416. if (strpos($cleansql, $note) !== false) {
  417. return error(3, 'SQL中包含注释信息');
  418. }
  419. }
  420. }
  421. } elseif (substr($cmd, 0, 2) === '/*') {
  422. return error(3, 'SQL中包含注释信息');
  423. }
  424. }
  425. private static function stripSafeChar($sql) {
  426. $len = strlen($sql);
  427. $mark = $clean = '';
  428. for ($i = 0; $i < $len; $i++) {
  429. $str = $sql[$i];
  430. switch ($str) {
  431. case '\'':
  432. if (!$mark) {
  433. $mark = '\'';
  434. $clean .= $str;
  435. } elseif ($mark == '\'') {
  436. $mark = '';
  437. }
  438. break;
  439. case '/':
  440. if (empty($mark) && $sql[$i + 1] == '*') {
  441. $mark = '/*';
  442. $clean .= $mark;
  443. $i++;
  444. } elseif ($mark == '/*' && $sql[$i - 1] == '*') {
  445. $mark = '';
  446. $clean .= '*';
  447. }
  448. break;
  449. case '#':
  450. if (empty($mark)) {
  451. $mark = $str;
  452. $clean .= $str;
  453. }
  454. break;
  455. case "\n":
  456. if ($mark == '#' || $mark == '--') {
  457. $mark = '';
  458. }
  459. break;
  460. case '-':
  461. if (empty($mark) && substr($sql, $i, 3) == '-- ') {
  462. $mark = '-- ';
  463. $clean .= $mark;
  464. }
  465. break;
  466. default:
  467. break;
  468. }
  469. $clean .= $mark ? '' : $str;
  470. }
  471. return $clean;
  472. }
  473. public static function parseParameter($params, $glue = ',', $alias = '') {
  474. $result = array('fields' => ' 1 ', 'params' => array());
  475. $split = '';
  476. $suffix = '';
  477. $allow_operator = array('>', '<', '<>', '!=', '>=', '<=', '+=', '-=', 'LIKE', 'like');
  478. if (in_array(strtolower($glue), array('and', 'or'))) {
  479. $suffix = '__';
  480. }
  481. if (!is_array($params)) {
  482. $result['fields'] = $params;
  483. return $result;
  484. }
  485. if (is_array($params)) {
  486. $result['fields'] = '';
  487. foreach ($params as $fields => $value) {
  488. if ($glue == ',') {
  489. $value = $value === null ? '' : $value;
  490. }
  491. $operator = '';
  492. if (strpos($fields, ' ') !== FALSE) {
  493. list($fields, $operator) = explode(' ', $fields, 2);
  494. if (!in_array($operator, $allow_operator)) {
  495. $operator = '';
  496. }
  497. }
  498. if (empty($operator)) {
  499. $fields = trim($fields);
  500. if (is_array($value) && !empty($value)) {
  501. $operator = 'IN';
  502. } elseif ($value === 'NULL') {
  503. $operator = 'IS';
  504. } else {
  505. $operator = '=';
  506. }
  507. } elseif ($operator == '+=') {
  508. $operator = " = `$fields` + ";
  509. } elseif ($operator == '-=') {
  510. $operator = " = `$fields` - ";
  511. } elseif ($operator == '!=' || $operator == '<>') {
  512. if (is_array($value) && !empty($value)) {
  513. $operator = 'NOT IN';
  514. } elseif ($value === 'NULL') {
  515. $operator = 'IS NOT';
  516. }
  517. }
  518. $select_fields = self::parseFieldAlias($fields, $alias);
  519. if (is_array($value) && !empty($value)) {
  520. $insql = array();
  521. $value = array_values($value);
  522. foreach ($value as $v) {
  523. $placeholder = self::parsePlaceholder($fields, $suffix);
  524. $insql[] = $placeholder;
  525. $result['params'][$placeholder] = is_null($v) ? '' : $v;
  526. }
  527. $result['fields'] .= $split . "$select_fields {$operator} (".implode(",", $insql).")";
  528. $split = ' ' . $glue . ' ';
  529. } else {
  530. $placeholder = self::parsePlaceholder($fields, $suffix);
  531. $result['fields'] .= $split . "$select_fields {$operator} " . ($value === 'NULL' ? 'NULL' : $placeholder);
  532. $split = ' ' . $glue . ' ';
  533. if ($value !== 'NULL') {
  534. $result['params'][$placeholder] = is_array($value) ? '' : $value;
  535. }
  536. }
  537. }
  538. }
  539. return $result;
  540. }
  541. private static function parsePlaceholder($field, $suffix = '') {
  542. static $params_index = 0;
  543. $params_index++;
  544. $illegal_str = array('(', ')', '.', '*');
  545. $placeholder = ":{$suffix}" . str_replace($illegal_str, '_', $field) . "_{$params_index}";
  546. return $placeholder;
  547. }
  548. private static function parseFieldAlias($field, $alias = '') {
  549. if (strexists($field, '.') || strexists($field, '*')) {
  550. return $field;
  551. }
  552. if (strexists($field, '(')) {
  553. $select_fields = str_replace(array('(', ')'), array('(' . (!empty($alias) ? "`{$alias}`." : '') .'`', '`)'), $field);
  554. } else {
  555. $select_fields = (!empty($alias) ? "`{$alias}`." : '') . "`$field`";
  556. }
  557. return $select_fields;
  558. }
  559. public static function parseSelect($field = array(), $alias = '') {
  560. if (empty($field) || $field == '*') {
  561. return ' SELECT *';
  562. }
  563. if (!is_array($field)) {
  564. $field = array($field);
  565. }
  566. $select = array();
  567. $index = 0;
  568. foreach ($field as $field_row) {
  569. if (strexists($field_row, '*')) {
  570. if (!strexists(strtolower($field_row), 'as')) {
  571. }
  572. } elseif (strexists(strtolower($field_row), 'select')) {
  573. if ($field_row[0] != '(') {
  574. $field_row = "($field_row) AS '{$index}'";
  575. }
  576. } elseif (strexists($field_row, '(')) {
  577. $field_row = str_replace(array('(', ')'), array('(' . (!empty($alias) ? "`{$alias}`." : '') . '`', '`)'), $field_row);
  578. if (!strexists(strtolower($field_row), 'as')) {
  579. $field_row .= " AS '{$index}'";
  580. }
  581. } else {
  582. $field_row = self::parseFieldAlias($field_row, $alias);
  583. }
  584. $select[] = $field_row;
  585. $index++;
  586. }
  587. return " SELECT " . implode(',', $select);
  588. }
  589. public static function parseLimit($limit, $inpage = true) {
  590. $limitsql = '';
  591. if (empty($limit)) {
  592. return $limitsql;
  593. }
  594. if (is_array($limit)) {
  595. if (empty($limit[0]) && !empty($limit[1])) {
  596. $limitsql = " LIMIT 0, " . $limit[1];
  597. } else {
  598. $limit[0] = max(intval($limit[0]), 1);
  599. !empty($limit[1]) && $limit[1] = max(intval($limit[1]), 1);
  600. if (empty($limit[0]) && empty($limit[1])) {
  601. $limitsql = '';
  602. } elseif (!empty($limit[0]) && empty($limit[1])) {
  603. $limitsql = " LIMIT " . $limit[0];
  604. } else {
  605. $limitsql = " LIMIT " . ($inpage ? ($limit[0] - 1) * $limit[1] : $limit[0]) . ', ' . $limit[1];
  606. }
  607. }
  608. } else {
  609. $limit = trim($limit);
  610. if (preg_match('/^(?:limit)?[\s,0-9]+$/i', $limit)) {
  611. $limitsql = strexists(strtoupper($limit), 'LIMIT') ? " $limit " : " LIMIT $limit";
  612. }
  613. }
  614. return $limitsql;
  615. }
  616. public static function parseOrderby($orderby, $alias = '') {
  617. $orderbysql = '';
  618. if (empty($orderby)) {
  619. return $orderbysql;
  620. }
  621. if (!is_array($orderby)) {
  622. $orderby = explode(',', $orderby);
  623. }
  624. foreach ($orderby as $i => &$row) {
  625. $row = strtolower($row);
  626. list($field, $orderbyrule) = explode(' ', $row);
  627. if ($orderbyrule != 'asc' && $orderbyrule != 'desc') {
  628. unset($orderby[$i]);
  629. }
  630. $field = self::parseFieldAlias($field, $alias);
  631. $row = "{$field} {$orderbyrule}";
  632. }
  633. $orderbysql = implode(',', $orderby);
  634. return !empty($orderbysql) ? " ORDER BY $orderbysql " : '';
  635. }
  636. public static function parseGroupby($statement, $alias = '') {
  637. if (empty($statement)) {
  638. return $statement;
  639. }
  640. if (!is_array($statement)) {
  641. $statement = explode(',', $statement);
  642. }
  643. foreach ($statement as $i => &$row) {
  644. $row = self::parseFieldAlias($row, $alias);
  645. if (strexists($row, ' ')) {
  646. unset($statement[$i]);
  647. }
  648. }
  649. $statementsql = implode(', ', $statement);
  650. return !empty($statementsql) ? " GROUP BY $statementsql " : '';
  651. }
  652. }