NewModel.class.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. <?php
  2. require_once dirname(__FILE__) . '/Core.class.php';
  3. require_once dirname(__FILE__) . '/Connect.class.php';
  4. /**
  5. * @property array table_name_alias
  6. */
  7. class NewModel
  8. {
  9. /**
  10. * [$sql 表别名]
  11. * [$table_alias 表别名]
  12. * [$field_alias 列别名]
  13. * [$prefix 表前缀]
  14. * [$query 请求参数]
  15. * @var array
  16. */
  17. private $table_alias, $field_alias, $prefix, $query = array(
  18. 'table' => '',
  19. 'field' => '',
  20. 'where' => '',
  21. 'order' => '',
  22. 'group' => '',
  23. 'limit' => '',
  24. );
  25. /**
  26. * [$table_name 表名]
  27. * @var string
  28. */
  29. protected $table_name = '';
  30. /**
  31. * 模型类目录地址
  32. * @var boolean
  33. */
  34. public static $sql, $lib = false;
  35. /**
  36. * 初始化
  37. * @param [type] $table_name [description]
  38. */
  39. public function __construct($table_name)
  40. {
  41. $this->prefix = DB_PREFIX;
  42. $this->table_name = $table_name;
  43. $this->resetQuery();
  44. }
  45. /**
  46. * 新建实体类
  47. * @param [type] $table [description]
  48. * @return Model [type] [description]
  49. */
  50. public static function build($table)
  51. {
  52. $class_name = $table . 'Model';
  53. if (self::$lib) {
  54. $file_name = self::$lib . '/models/' . $class_name . '.class.php';
  55. if (!class_exists($class_name) && file_exists($file_name)) {
  56. require_once $file_name;
  57. }
  58. }
  59. return class_exists($class_name) ? new $class_name($table) : new NewModel($table);
  60. }
  61. /**
  62. * $query请求参数设置
  63. * @param string $name 参数名
  64. * @param array $args 参数值
  65. * @return $this [type] [description]
  66. */
  67. public function __call($name, $args)
  68. {
  69. if (array_key_exists($name, $this->query)) {
  70. switch (sizeof($args)) {
  71. case 0:
  72. return $this->query[$name];
  73. break;
  74. case 1:
  75. if ($args[0]) {
  76. $this->query[$name] = self::stringToArray($args[0]);
  77. }
  78. break;
  79. default:
  80. $this->query[$name] = $args;
  81. break;
  82. }
  83. return $this;
  84. } else {
  85. switch ($name) {
  86. case 'count':
  87. $args[1] = $args[0];
  88. $field = 1;
  89. case 'sum':
  90. case 'min':
  91. case 'max':
  92. if (isset($args[0])) {
  93. $field = isset($field) ? $field : $this->getFullField($args[0]);
  94. $res = $this->field(array(array("$name($field) $name")))->selectOne($args[1]);
  95. return $res[$name];
  96. }
  97. default:
  98. Core::error('function ' . $name . ' is not found!');
  99. break;
  100. }
  101. }
  102. }
  103. /**
  104. * 获取上一条数据库语句
  105. * @return string [description]
  106. */
  107. public function getLastSql()
  108. {
  109. return self::$sql;
  110. }
  111. /**
  112. * 查询
  113. * @param string $where [description]
  114. * @return array [description]
  115. */
  116. public function select($where = '')
  117. {
  118. self::$sql = $this->where($where)->getSelectSql();
  119. $this->resetQuery();
  120. return Connect::query(self::$sql);
  121. }
  122. /**
  123. * 查询一条记录
  124. * @param string $where [description]
  125. * @return array [description]
  126. */
  127. public function selectOne($where = '')
  128. {
  129. self::$sql = $this->where($where)->limit(1)->getSelectSql();
  130. $this->resetQuery();
  131. return Connect::query(self::$sql, 0);
  132. }
  133. /**
  134. * 插入
  135. * @param array $data [description]
  136. * @return int [description]
  137. */
  138. public function insert($data)
  139. {
  140. self::$sql = $this->getInsertSql($data);
  141. $this->resetQuery();
  142. return Connect::exec(self::$sql) ? Connect::lastInsertId() : false;
  143. }
  144. /**
  145. * 更新
  146. * @param array $data [description]
  147. * @param string $where [description]
  148. * @return int [description]
  149. */
  150. public function update($data, $where = '')
  151. {
  152. self::$sql = $this->where($where)->getUpdateSql($data);
  153. $this->resetQuery();
  154. return Connect::exec(self::$sql);
  155. }
  156. /**
  157. * 删除
  158. * @param string $where [description]
  159. * @return [type] [description]
  160. */
  161. public function delete($where = '')
  162. {
  163. self::$sql = $this->where($where)->getDeleteSql();
  164. $this->resetQuery();
  165. return Connect::exec(self::$sql);
  166. }
  167. /**
  168. * 重置请求参数
  169. * @return void
  170. */
  171. public function resetQuery()
  172. {
  173. $this->query = array(
  174. 'table' => '',
  175. 'field' => '',
  176. 'where' => '',
  177. 'order' => '',
  178. 'group' => '',
  179. 'limit' => '',
  180. );
  181. $this->table_name_alias = array();
  182. $this->field_alias = array();
  183. }
  184. /**
  185. * 获取查询sql语句
  186. * @return string [type] [description]
  187. */
  188. private function getSelectSql()
  189. {
  190. $table = $this->getTableSql() ?: $this->getTableName($this->table_name);
  191. $field = $this->getFieldSql() ?: '*';
  192. $where = $this->getWhereSql();
  193. $order = $this->getOrderSql();
  194. $group = $this->getGroupSql();
  195. $limit = $this->getLimitSql();
  196. return "SELECT $field FROM $table$where$group$order$limit;";
  197. }
  198. /**
  199. * 获取插入sql语句
  200. * @param array $data [description]
  201. * @return string [type] [description]
  202. */
  203. private function getInsertSql($data)
  204. {
  205. $table = $this->getTableName($this->table_name);
  206. $column = '';
  207. $values = '';
  208. foreach ($data as $key => $value) {
  209. $column .= '`' . $key . '`,';
  210. $values .= '\'' . addslashes($value) . '\',';
  211. }
  212. $column = rtrim($column, ',');
  213. $values = rtrim($values, ',');
  214. return "INSERT INTO $table ($column) VALUES($values);";
  215. }
  216. /**
  217. * 获取更新sql语句
  218. * @param array $data [description]
  219. * @return string [type] [description]
  220. */
  221. private function getUpdateSql($data)
  222. {
  223. $table = $this->getTableName($this->table_name);
  224. $values = '';
  225. foreach ($data as $key => $value) {
  226. if (is_array($value)) {
  227. $values .= $this->getFieldName($key) . '=' . $value[0] . ',';
  228. } else {
  229. $values .= $this->getFieldName($key) . '=\'' . addslashes($value) . '\',';
  230. }
  231. }
  232. $values = rtrim($values, ',');
  233. $where = $this->getWhereSql();
  234. if (empty($where)) {
  235. Core::error("update where is error");
  236. }
  237. return "UPDATE $table SET $values$where;";
  238. }
  239. /**
  240. * 获取删除sql语句
  241. * @return string [type] [description]
  242. */
  243. private function getDeleteSql()
  244. {
  245. $table = $this->getTableName($this->table_name);
  246. $where = $this->getWhereSql();
  247. if (empty($where)) {
  248. Core::error("delete where is error");
  249. }
  250. return "DELETE FROM $table$where";
  251. }
  252. /**
  253. * 获取表名sql语句
  254. * @return string [type] [description]
  255. */
  256. private function getTableSql()
  257. {
  258. $tables = $this->query['table'];
  259. if ($tables) {
  260. $this->table_alias = array();
  261. $sql = '';
  262. foreach ($tables as $key => $table) {
  263. if (is_string($key) && is_array($table)) {
  264. $on = false;
  265. foreach ($table as $k => $v) {
  266. $k = strtoupper(self::mergeSpaces($k));
  267. switch ($k) {
  268. case '0':
  269. $option = $v;
  270. break;
  271. case 'JOIN':
  272. case 'LEFT JOIN':
  273. case 'RIGHT JOIN':
  274. $option = $k;
  275. case '1':
  276. $table2 = self::getFullTable(self::mergeSpaces($v));
  277. break;
  278. case '2':
  279. case 'ON':
  280. $on = $v;
  281. break;
  282. default:
  283. break;
  284. }
  285. }
  286. $table1 = self::getFullTable(self::mergeSpaces($key));
  287. $on = $on ? 'ON' . $this->getWhereSql($on) : '';
  288. $sql .= "$table1 $option $table2$on,";
  289. } else {
  290. $sql .= self::getFullTable(self::mergeSpaces($table)) . ',';
  291. }
  292. }
  293. return rtrim($sql, ',');
  294. } else {
  295. return '';
  296. }
  297. }
  298. /**
  299. * 获取列名sql语句
  300. * @return string [type] [description]
  301. */
  302. private function getFieldSql()
  303. {
  304. $fields = $this->query['field'];
  305. if ($fields) {
  306. $sql = '';
  307. foreach ($fields as $field) {
  308. if ($field) {
  309. if (is_array($field)) {
  310. $sql .= $field[0] . ',';
  311. } else {
  312. $sql .= $this->getFullField(self::mergeSpaces($field)) . ',';
  313. }
  314. }
  315. }
  316. return rtrim($sql, ',');
  317. } else {
  318. return '';
  319. }
  320. }
  321. /**
  322. * 获取条件sql语句
  323. * @return string [type] [description]
  324. */
  325. private function getWhereSql($wheres = false)
  326. {
  327. if ($wheres === false) {
  328. $wheres = $this->query['where'];
  329. if ($wheres) {
  330. return ' WHERE' . $this->getWhereSql($wheres);
  331. } else {
  332. return '';
  333. }
  334. } else {
  335. $sql = '';
  336. foreach ($wheres as $key => $value) {
  337. if (is_array($value) && !is_string($key)) {
  338. $sql_item = '';
  339. foreach ($value as $k => $v) {
  340. $sql_item .= $this->getWhereItem($k, $v);
  341. }
  342. $pre = substr($sql_item, 0, strpos($sql_item, ' ') + 1);
  343. $sql .= $pre . '( ' . ltrim($sql_item, $pre) . ')';
  344. } else {
  345. $sql .= $this->getWhereItem($key, $value);
  346. }
  347. }
  348. return ltrim($sql, 'AND');
  349. }
  350. }
  351. /**
  352. * 获取排序sql语句
  353. * @return string [type] [description]
  354. */
  355. private function getOrderSql()
  356. {
  357. $orders = $this->query['order'];
  358. if ($orders) {
  359. $sql = ' ORDER BY ';
  360. foreach ($orders as $order) {
  361. if (is_array($order)) {
  362. $sql .= $order[0] . ',';
  363. } else {
  364. $order = self::stringToArray($order, ' ');
  365. $order_sql = '';
  366. switch (sizeof($order)) {
  367. case 2:
  368. $order_sql = ' ' . $order[1];
  369. case 1:
  370. $order_sql = $this->getFieldName($order[0]) . $order_sql;
  371. break;
  372. default:
  373. throw new Exception("select order is error");
  374. break;
  375. }
  376. $sql .= $order_sql . ',';
  377. }
  378. }
  379. return rtrim($sql, ',');
  380. } else {
  381. return '';
  382. }
  383. }
  384. /**
  385. * 获取分组sql语句
  386. * @return string [type] [description]
  387. */
  388. private function getGroupSql()
  389. {
  390. $groups = $this->query['group'];
  391. if ($groups) {
  392. $sql = ' GROUP BY ';
  393. foreach ($groups as $group) {
  394. if (is_array($group)) {
  395. $sql .= $group[0] . ',';
  396. } else {
  397. $sql .= $this->getFieldName($group) . ',';
  398. }
  399. }
  400. return rtrim($sql, ',');
  401. } else {
  402. return '';
  403. }
  404. }
  405. /**
  406. * 获取限制sql语句
  407. * @return string [type] [description]
  408. */
  409. private function getLimitSql()
  410. {
  411. $limit = $this->query['limit'];
  412. if ($limit) {
  413. $sql = '';
  414. switch (sizeof($limit)) {
  415. case 2:
  416. $sql = ',' . intval($limit[1]);
  417. case 1:
  418. $sql = intval($limit[0]) . $sql;
  419. break;
  420. default:
  421. Core::error("select limit is error");
  422. break;
  423. }
  424. return ' LIMIT ' . $sql;
  425. } else {
  426. return '';
  427. }
  428. }
  429. /**
  430. * 获取条件单元sql语句
  431. * @param string $key [description]
  432. * @param [type] $val [description]
  433. * @return string [type] [description]
  434. */
  435. private function getWhereItem($key, $val)
  436. {
  437. if (is_array($val)) {
  438. if (sizeof($val) == 1) {
  439. $val[3] = 1;
  440. $val[2] = 'AND';
  441. $val[1] = $val[0];
  442. $val[0] = '=';
  443. }
  444. $option = self::whereOp($val[0]);
  445. $value = $val[1];
  446. $rule = isset($val[2]) ? $val[2] : 'AND';
  447. $is_field = isset($val[3]) ? $val[3] : 0;
  448. switch ($option) {
  449. case 'EXP':
  450. return $value . ' ';
  451. break;
  452. case 'IN':
  453. case 'NOT IN':
  454. $value = self::stringToArray($value);
  455. foreach ($value as $k => $v) {
  456. $value[$k] = '\'' . addslashes($v) . '\'';
  457. }
  458. return $rule . ' ' . $this->getFieldName($key) . ' ' . $option . ' (' . implode(',', $value) . ') ';
  459. break;
  460. case 'BETWEEN':
  461. $value = self::stringToArray($value);
  462. return $rule . ' (' . $this->getFieldName($key) . ' BETWEEN \'' . addslashes($value[0]) . '\' AND \'' . addslashes($value[1]) . '\') ';
  463. break;
  464. default:
  465. return $rule . ' ' . $this->getFieldName($key) . ' ' . $option . ' ' . ($is_field ? $this->getFieldName($value) : ('\'' . addslashes($value) . '\'')) . ' ';
  466. break;
  467. }
  468. } else {
  469. return 'AND ' . $this->getFieldName($key) . ' = \'' . addslashes($val) . '\'';
  470. }
  471. }
  472. /**
  473. * 获取单个完整表名sql语句,包含别名
  474. * @param string $table_str [description]
  475. * @return string [type] [description]
  476. */
  477. private function getFullTable($table_str)
  478. {
  479. $table = self::stringToArray($table_str, ' ');
  480. $sql = '';
  481. switch (sizeof($table)) {
  482. case 3:
  483. if (strtoupper($table[1]) == 'AS') {
  484. $table[1] = $table[2];
  485. } else {
  486. Core::error("select table '$table_str' is error");
  487. }
  488. case 2:
  489. // 表别名
  490. $sql = ' AS `' . $table[1] . '`';
  491. $this->table_alias[] = $table[1];
  492. case 1:
  493. $sql = $this->getTableName($table[0]) . $sql;
  494. break;
  495. default:
  496. Core::error("select table '$table_str' is error");
  497. break;
  498. }
  499. return $sql;
  500. }
  501. /**
  502. * 获取完整表名
  503. * @param string $table_str [description]
  504. * @return string [type] [description]
  505. */
  506. private function getTableName($table_str)
  507. {
  508. $table = array_reverse(self::stringToArray($table_str, '.'), 0);
  509. $sql = '';
  510. switch (sizeof($table)) {
  511. case 2:
  512. $sql = '`' . $table[1] . '`.';
  513. case 1:
  514. $sql .= '`' . $this->prefix . $table[0] . '`';
  515. break;
  516. default:
  517. Core::error("select table '$table_str' is error");
  518. break;
  519. }
  520. return $sql;
  521. }
  522. /**
  523. * 获取单个列名完整语句,包括别名
  524. * @param string $field_str [description]
  525. * @return string [type] [description]
  526. */
  527. private function getFullField($field_str)
  528. {
  529. $field = self::stringToArray($field_str, ' ');
  530. $sql = '';
  531. switch (sizeof($field)) {
  532. case 3:
  533. if (strtoupper($field[1]) == 'AS') {
  534. $field[1] = $field[2];
  535. } else {
  536. Core::error("select field '$field_str' is error");
  537. }
  538. case 2:
  539. // 列别名
  540. $sql = ' AS `' . $field[1] . '`';
  541. case 1:
  542. $sql = $this->getFieldName($field[0]) . $sql;
  543. break;
  544. default:
  545. Core::error("select field '$field_str' is error");
  546. break;
  547. }
  548. return $sql;
  549. }
  550. /**
  551. * 获取完整列名
  552. * @param string $field_str [description]
  553. * @return string [type] [description]
  554. */
  555. private function getFieldName($field_str)
  556. {
  557. $field = array_reverse(self::stringToArray($field_str, '.'), 0);
  558. $sql = '';
  559. switch (sizeof($field)) {
  560. case 3:
  561. // 数据库名
  562. $sql .= '`' . $field[2] . '`.';
  563. case 2:
  564. // 表名
  565. if (in_array($field[1], $this->table_alias)) {
  566. $sql .= '`' . $field[1] . '`.';
  567. } else {
  568. $sql .= '`' . $this->prefix . $field[1] . '`.';
  569. }
  570. case 1:
  571. // 列名
  572. $sql .= $field[0] == '*' ? '*' : ('`' . $field[0] . '`');
  573. break;
  574. default:
  575. Core::error("select field '$field_str' is error");
  576. break;
  577. }
  578. return $sql;
  579. }
  580. /**
  581. * 字符串转数组
  582. * @param [type] $string [description]
  583. * @param string $delimiter [description]
  584. * @return array [type] [description]
  585. */
  586. private static function stringToArray($string, $delimiter = ',')
  587. {
  588. if (!is_array($string) && !empty($string)) {
  589. return explode($delimiter, $string);
  590. }
  591. return $string;
  592. }
  593. /**
  594. * 去除字符串多余空格
  595. * @param string $string [description]
  596. * @return mixed [type] [description]
  597. */
  598. private static function mergeSpaces($string)
  599. {
  600. return preg_replace('/\s(?=\s)/', '\\1', trim($string));
  601. }
  602. /**
  603. * 判断数组是否为键值对
  604. * @param [type] $arr [description]
  605. * @return boolean [description]
  606. */
  607. private static function isAssoc($arr)
  608. {
  609. if (!is_array($arr)) {
  610. return false;
  611. }
  612. return array_keys($arr) !== range(0, count($arr) - 1);
  613. }
  614. /**
  615. * 条件参数过滤
  616. * @param string $value [description]
  617. * @return string [type] [description]
  618. */
  619. private static function whereOp($value)
  620. {
  621. $value = strtoupper($value);
  622. switch ($value) {
  623. case 'EQ':
  624. return '=';
  625. case 'NEQ':
  626. return '<>';
  627. case 'GT':
  628. return '>';
  629. case 'EGT':
  630. return '>=';
  631. case 'LT':
  632. return '<';
  633. case 'ELT':
  634. return '<=';
  635. case 'NOTLIKE':
  636. return 'NOT LIKE';
  637. default:
  638. return $value;
  639. break;
  640. }
  641. }
  642. }