db.class.php 21 KB

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