人人商城

db.class.php 21KB

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