Base.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. <?php
  2. namespace Qii\Driver;
  3. class Base
  4. {
  5. const VERSION = '1.2';
  6. public $_cache;
  7. public $language;
  8. protected $_query = array(
  9. "INSERT" => "INSERT INTO %s(%s) VALUES('%s')",
  10. "REPLACE" => "REPLACE %s (%s) VALUES('%s')",
  11. "SELECT" => "SELECT %s FROM %s",
  12. "UPDATE" => "UPDATE %s SET ",
  13. "DELETE" => "DELETE FROM %s %s",
  14. "WHERE" => " WHERE %s",
  15. "ORDER" => " ORDER BY %s %s",
  16. "GROUP" => " GROUP BY %s",
  17. "LIMIT" => " LIMIT %d, %d"
  18. );
  19. private $query;
  20. private $setArray = array();
  21. public $modelSQL = "";
  22. protected $fields;
  23. protected $where;
  24. protected $groupBy;
  25. protected $limit;
  26. protected $orderBy;
  27. public $load;
  28. /**
  29. * @var string $_response Response对象
  30. */
  31. protected $_response;
  32. //方法对应的别名
  33. protected $_modelAlias = array('selectRows' => 'selectAll', 'select' => 'selectRow', 'getOne' => 'selectOne', 'getRow' => 'selectRow', 'getAll' => 'selectAll', 'remove' => 'deleteRows');
  34. public function __construct()
  35. {
  36. $this->language = \Qii\Autoloader\Psr4::getInstance()->loadClass('Qii\Language\Loader');
  37. $this->load = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Autoloader\Loader');
  38. $this->_response = new \Qii\Driver\Response();
  39. }
  40. /**
  41. * 获取当前数据库中所有的表
  42. * @return array
  43. */
  44. public function getAllTables()
  45. {
  46. $sql = "SHOW TABLES";
  47. $rs = $this->setQuery($sql);
  48. $tables = array();
  49. while($row = $this->fetch($rs))
  50. {
  51. if(is_array($row)) {
  52. foreach($row AS $val) {
  53. $tables[] = $val;
  54. }
  55. }
  56. }
  57. return $tables;
  58. }
  59. /**
  60. * 查询数据库中是否有指定的表
  61. * @param string $tableName 表名
  62. * @return bool
  63. */
  64. public function hasTable($tableName)
  65. {
  66. $sql = "SHOW TABLES LIKE '".$tableName."'";
  67. $rs = $this->setQuery($sql);
  68. $tables = array();
  69. while($row = $this->fetch($rs))
  70. {
  71. if(is_array($row)) {
  72. foreach($row AS $val) {
  73. if($val == $tableName) return true;
  74. }
  75. }
  76. }
  77. return false;
  78. }
  79. /**
  80. * 获取创建表的SQL语句
  81. * @param string $tableName 表名
  82. * @param int|null $autoIncr 自增长的值,null的话就不使用
  83. * @return string
  84. */
  85. public function getTableSQL($tableName, $autoIncr = null)
  86. {
  87. $row = $this->getRow("SHOW CREATE TABLE `".$tableName."`");
  88. if(!$row) {
  89. throw new \Exception('数据表不存在', __LINE__);
  90. }
  91. $sql = $row['Create Table'];
  92. if($autoIncr === null) {
  93. return $sql;
  94. }
  95. return preg_replace("/AUTO_INCREMENT=[\d]{1,}/", "AUTO_INCREMENT=". intval($autoIncr), $sql);
  96. }
  97. final public function getAlias($alias)
  98. {
  99. return isset($this->_modelAlias[$alias]) ? $this->_modelAlias[$alias] : null;
  100. }
  101. /**
  102. * 设置Cache
  103. *
  104. * @param String $cache
  105. * @param Array $policy
  106. */
  107. final public function setCache($cache, $policy)
  108. {
  109. \Qii\Autoloader\Import::requires(Qii_DIR . DS . 'Qii' . DS . 'Cache.php');
  110. $this->_cache = \Qii\Autoloader\Psr4::loadClass('\Qii\Cache', $cache)->initialization($policy);//载入cache类文件
  111. }
  112. /**
  113. * 缓存内容
  114. *
  115. * @param String $id
  116. * @param Array $value
  117. * @return Bool
  118. */
  119. final public function cache($id, $value)
  120. {
  121. return $this->_cache->set($id, $value);
  122. }
  123. /**
  124. * 获取缓存的类
  125. */
  126. final public function getCache()
  127. {
  128. return $this->_cache;
  129. }
  130. /**
  131. * 获取缓存内容
  132. *
  133. * @param String $id
  134. * @return Array
  135. */
  136. final public function getCacheData($id)
  137. {
  138. return $this->_cache->get($id);
  139. }
  140. /**
  141. * 获取表的名称
  142. * @param String $table
  143. * @return String
  144. */
  145. public function getTable($table)
  146. {
  147. return $table;
  148. }
  149. public function setLanguage()
  150. {
  151. $this->language = \Qii\Autoloader\Psr4::loadClass('Qii_Language_Loader');
  152. }
  153. /**
  154. *
  155. * Insert Object
  156. * @param String $table
  157. * @param Array|Object $dataArray
  158. */
  159. final function insertObject($table, $dataArray)
  160. {
  161. if (empty($table)) {
  162. return -1;
  163. }
  164. if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
  165. $keys = array();
  166. $values = array();
  167. foreach ($dataArray AS $key => $value) {
  168. $keys[] = $key;
  169. if(is_array($value))
  170. {
  171. throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
  172. }
  173. $values[] = $this->setQuote($value);
  174. }
  175. $this->modelSQL = $sql = "INSERT INTO `{$table}`(`" . join("`, `", $keys) . "`) VALUES('" . join("', '", $values) . "')";
  176. $this->setQuery($sql);
  177. $this->cleanData();
  178. $this->setError();
  179. return $this->lastInsertId();
  180. }
  181. return -2;
  182. }
  183. /**
  184. *
  185. * Replace Object
  186. * @param String $table
  187. * @param Array|Object $dataArray
  188. */
  189. final function replaceObject($table, $dataArray)
  190. {
  191. if (empty($table)) {
  192. return -1;
  193. }
  194. if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
  195. $keys = array();
  196. $values = array();
  197. foreach ($dataArray AS $key => $value) {
  198. $keys[] = $key;
  199. if(is_array($value))
  200. {
  201. throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
  202. }
  203. $values[] = $this->setQuote($value);
  204. }
  205. $this->modelSQL = $sql = "REPLACE INTO `{$table}`(`" . join("`, `", $keys) . "`) VALUES('" . join("', '", $values) . "')";
  206. $rs = $this->setQuery($sql);
  207. $this->cleanData();
  208. $this->setError();
  209. return $this->AffectedRows($rs);
  210. }
  211. return -2;
  212. }
  213. /**
  214. *
  215. * Update data
  216. * @param String $table
  217. * @param Array|Objct $dataArray
  218. * @param Array $keys
  219. */
  220. final function updateObject($table, $dataArray, $keys = array())
  221. {
  222. if (empty($table) || !is_array($keys)) {
  223. return -1;
  224. }
  225. if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
  226. $values = array();
  227. $where = array();
  228. foreach ($dataArray AS $key => $value) {
  229. if(is_array($value))
  230. {
  231. throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
  232. }
  233. $value = $this->setQuote($value);
  234. if (in_array($key, $keys)) {
  235. $where[] = "`{$key}` = '" . $value . "'";
  236. } else {
  237. $values[] = "`{$key}` = '" . $value . "'";
  238. }
  239. }
  240. //$keys为key => value的方式,就直接用keys
  241. if (empty($where) && count($keys) > 0) {
  242. foreach ($keys as $key => $value) {
  243. $value = $this->setQuote($value);
  244. $where[] = "`{$key}` = '" . $value . "'";
  245. }
  246. }
  247. $this->modelSQL = $sql = "UPDATE `{$table}` SET " . join(", ", $values) . (sizeof($where) > 0 ? " WHERE " . join(" AND ", $where) : '');
  248. $rs = $this->setQuery($sql);
  249. $this->cleanData();
  250. $this->setError();
  251. return $this->AffectedRows($rs);
  252. }
  253. return 0;
  254. }
  255. /**
  256. *
  257. * 删除数据
  258. * @param String $table
  259. * @param Array $keys
  260. */
  261. final function deleteObject($table, $keys = array())
  262. {
  263. if (empty($table)) {
  264. return -1;
  265. }
  266. $where = array();
  267. if (sizeof($keys) > 0 || get_object_vars($keys)) {
  268. foreach ($keys AS $k => $v) {
  269. $where[] = "`{$k}` = '" . $this->setQuote($v) . "'";
  270. }
  271. }
  272. $this->modelSQL = $sql = "DELETE FROM `{$table}`" . (sizeof($where) > 0 ? " WHERE " . join(" AND ", $where) : '');
  273. $rs = $this->query($sql);
  274. $this->cleanData();
  275. $this->setError();
  276. return $this->AffectedRows($rs);
  277. }
  278. /**
  279. * 需要清除的数据
  280. *
  281. * @return Array
  282. */
  283. final function cleanOptions()
  284. {
  285. return array('fields', 'where', 'groupBy', 'orderBy', 'limit', 'setArray');
  286. }
  287. /**
  288. * 清除数据
  289. *
  290. */
  291. final function cleanData()
  292. {
  293. $array = $this->cleanOptions();
  294. foreach ($array AS $k) {
  295. if (is_array($this->$k)) {
  296. $this->$k = array();
  297. } else {
  298. $this->$k = null;
  299. }
  300. }
  301. }
  302. /**
  303. *
  304. * 查询的字段
  305. * @param String $fileds
  306. */
  307. final function fields($fileds = "*")
  308. {
  309. $this->fields = null;
  310. if (empty($fileds)) $fileds = "*";
  311. if (is_array($fileds)) $fileds = join(',', $fileds);
  312. $this->fields = $fileds;
  313. return $this;
  314. }
  315. /**
  316. *
  317. * GROUP BY方法
  318. * @param String $fields
  319. */
  320. final function groupBy($fields)
  321. {
  322. $this->groupBy = null;
  323. if (!empty($fields)) {
  324. $this->groupBy = sprintf($this->_query['GROUP'], $fields);
  325. }
  326. return $this;
  327. }
  328. /**
  329. *
  330. * 插入数据用
  331. * @param Array $array
  332. */
  333. final function dataArray($array)
  334. {
  335. $this->fileds = null;
  336. if (is_array($array)) {
  337. $tmpArray = array();
  338. foreach ($array AS $k => $v) {
  339. $tmpArray['k'][] = $k;
  340. $tmpArray['v'][] = $this->setQuote($v);
  341. }
  342. $this->fileds = $tmpArray;
  343. }
  344. return $this;
  345. }
  346. /**
  347. *
  348. * Order By函数
  349. * @param String $field
  350. * @param String $orderBy
  351. */
  352. final function orderBy($field, $orderBy)
  353. {
  354. $this->orderBy = null;
  355. if (!empty($field)) {
  356. $this->orderBy = sprintf($this->_query['ORDER'], $field, $orderBy);
  357. }
  358. return $this;
  359. }
  360. /**
  361. *
  362. * Limit函数,如果省略第二个参数则第一个为0,第二个参数值取第一个
  363. * @param Int $limit
  364. * @param Int $offset
  365. */
  366. final function limit($limit, $offset = 0)
  367. {
  368. $this->limit = null;
  369. if ($limit !== '') {
  370. if (!$offset) {
  371. $this->limit = sprintf($this->_query["LIMIT"], 0, $limit);
  372. } else {
  373. $this->limit = sprintf($this->_query["LIMIT"], $limit, $offset);
  374. }
  375. }
  376. return $this;
  377. }
  378. /**
  379. * 传的条件为数组
  380. * @param Array $where 条件
  381. * @return Object 对象本身
  382. */
  383. final function whereArray($where)
  384. {
  385. $this->where = null;
  386. if (!empty($where)) {
  387. $whereArray = array();
  388. foreach ($where AS $k => $v) {
  389. $whereArray[] = " `{$k}` = '{$v}'";
  390. }
  391. if (sizeof($whereArray) > 0) {
  392. $whereSQL = join(" AND ", $whereArray);
  393. $this->where = sprintf($this->_query["WHERE"], $whereSQL);
  394. }
  395. }
  396. return $this;
  397. }
  398. /**
  399. *
  400. * WHERE 子句
  401. * @param String $where
  402. */
  403. final function where($where)
  404. {
  405. if (is_array($where)) return $this->whereArray($where);
  406. $this->where = null;
  407. if (!empty($where)) {
  408. $this->where = sprintf($this->_query["WHERE"], $where);
  409. }
  410. return $this;
  411. }
  412. /**
  413. *
  414. * 插入数据到指定表中
  415. * @param String $table
  416. */
  417. final function insertRow($table)
  418. {
  419. $this->modelSQL = $sql = sprintf($this->_query['INSERT'], $table, join(",", $this->fileds['k']), join("', '", $this->fileds['v']));
  420. $this->cleanData();
  421. $this->setQuery($sql, '');
  422. return $this->lastInsertId();
  423. }
  424. /**
  425. *
  426. * Replace方法
  427. * @param String $table
  428. */
  429. final function replaceRow($table)
  430. {
  431. $this->modelSQL = $sql = sprintf($this->_query['REPLACE'], $table, join(",", $this->fileds['k']), join("', '", $this->fileds['v']));
  432. $this->cleanData();
  433. return $this->exec($sql);
  434. }
  435. /**
  436. *
  437. * 查询一行
  438. * @param String $table
  439. */
  440. final function selectRow($table)
  441. {
  442. $this->modelSQL = $sql = sprintf($this->_query['SELECT'], ((trim($this->fields) != '') ? $this->fields : "*"), $table) . $this->where . $this->groupBy . $this->orderBy . $this->limit;
  443. $this->cleanData();
  444. return $this->getRow($sql);
  445. }
  446. /**
  447. *
  448. * 查询一行
  449. * @param String $table
  450. */
  451. final function selectOne($table)
  452. {
  453. $this->modelSQL = $sql = sprintf($this->_query['SELECT'], ((trim($this->fields) != '') ? $this->fields : "*"), $table) . $this->where . $this->groupBy . $this->orderBy . $this->limit;
  454. $this->cleanData();
  455. return $this->getOne($sql);
  456. }
  457. /**
  458. *
  459. * 查询所有
  460. * @param String $table
  461. * @return Array
  462. */
  463. final function selectAll($table)
  464. {
  465. $this->modelSQL = $sql = sprintf($this->_query['SELECT'], ((trim($this->fields) != '') ? $this->fields : "*"), $table) . $this->where . $this->groupBy . $this->orderBy . $this->limit;
  466. $this->cleanData();
  467. return $this->getAll($sql);
  468. }
  469. /**
  470. * 将指定字段减指定值
  471. *
  472. * @param $data
  473. * @return $this
  474. */
  475. final function downsetCounter($data)
  476. {
  477. if (is_array($data)) {
  478. foreach ($data AS $k => $value) {
  479. $this->setArray[] = $k . "=" . $k . '-' . $value;
  480. }
  481. }
  482. $this->set(null);
  483. return $this;
  484. }
  485. /**
  486. * 将指定字段加指定值
  487. *
  488. * @param $data
  489. * @return $this
  490. */
  491. final function upsetCounter($data)
  492. {
  493. if (is_array($data)) {
  494. foreach ($data AS $k => $value) {
  495. $this->setArray[] = $k . "=" . $k . '+' . $value;
  496. }
  497. }
  498. $this->set(null);
  499. return $this;
  500. }
  501. /**
  502. * 更新数据时候用,方法同setData
  503. * @param Array $data
  504. */
  505. final function set($data)
  506. {
  507. return $this->setData($data);
  508. }
  509. /**
  510. *
  511. * 更新数据时候用
  512. * @param Array $data
  513. * @return $this
  514. */
  515. final function setData($data)
  516. {
  517. if (is_array($data)) {
  518. $set = array();
  519. foreach ($data AS $k => $value) {
  520. $set[] = $k . "='" . $this->setQuote($value) . "'";
  521. }
  522. if (sizeof($this->setArray) > 0) {
  523. $this->set = " " . join(", ", $set) . ", " . join(",", $this->setArray);
  524. } else {
  525. $this->set = " " . join(", ", $set);
  526. }
  527. } else {
  528. if (sizeof($this->setArray) > 0) {
  529. $this->set = join(",", $this->setArray);
  530. } else {
  531. $this->set = "";
  532. }
  533. }
  534. return $this;
  535. }
  536. /**
  537. * 执行更新操作,updateRows的alias
  538. * @param String $table
  539. * @return number
  540. */
  541. /*
  542. final function update($table){
  543. return $this->updateRows($table);
  544. }
  545. */
  546. /**
  547. *
  548. * 执行更新操作
  549. * @param $table
  550. * @return Int 返回影响的行数
  551. */
  552. final function updateRows($table)
  553. {
  554. $this->modelSQL = $sql = sprintf($this->_query['UPDATE'], $table) . $this->set . $this->where . $this->limit;
  555. $this->cleanData();
  556. return $this->exec($sql);
  557. }
  558. /**
  559. *
  560. * 执行删除操作
  561. * @param String $table
  562. */
  563. final function deleteRows($table)
  564. {
  565. $this->modelSQL = $sql = sprintf($this->_query['DELETE'], $table, $this->where) . $this->limit;
  566. $this->cleanData();
  567. return $this->exec($sql);
  568. }
  569. /**
  570. * 执行Model过程中保存的相关信息
  571. *
  572. * @param String $option
  573. * @return Mix
  574. */
  575. final function querySQL($option = '')
  576. {
  577. $allow = array('_queryTimes', '_querySeconds', '_errorInfo', '_exeSQL');
  578. if (in_array($option, $allow)) {
  579. return $this->{$option};
  580. }
  581. return 0;
  582. }
  583. /**
  584. * 将结果编码一下
  585. * @param String $word
  586. * @return String|multitype:
  587. */
  588. public function setQuote($word)//过滤sql字符
  589. {
  590. if (ini_get("magic_quotes_gpc")) {
  591. return $word;
  592. }
  593. return is_array($word) ? array_map('addslashes', $word) : addslashes($word);
  594. }
  595. /**
  596. * 获取错误码
  597. */
  598. public function getCode()
  599. {
  600. return $this->_response->getCode();
  601. }
  602. /**
  603. * 获取错误信息
  604. */
  605. public function getMessage()
  606. {
  607. if($this->_response->isError())
  608. {
  609. return $this->_response->getMessage();
  610. }
  611. }
  612. /**
  613. * 返回response对象
  614. *
  615. * @return Bool
  616. */
  617. public function getResponse()
  618. {
  619. return $this->_response;
  620. }
  621. public function iconv($str)
  622. {
  623. if (is_array($str)) {
  624. return array_map(function ($n) {
  625. return iconv('GB2312', 'UTF-8', $n);
  626. }, $str);
  627. }
  628. return iconv('GB2312', 'UTF-8', $str);
  629. }
  630. /**
  631. * 如果不存在指定的方法则调用提示错误
  632. *
  633. * @param String $name
  634. * @param Mix $args
  635. * @return Mix
  636. */
  637. public function __call($method, $argvs)
  638. {
  639. if (isset($this->_modelAlias[$method])) {
  640. if (method_exists($this, $this->_modelAlias[$method])) {
  641. return call_user_func_array(array($this, $this->_modelAlias[$method]), $argvs);
  642. }
  643. \Qii::setError(false, __LINE__, 1506, 'Alias ' . get_called_class() . '->' . $method . '()');
  644. }
  645. \Qii::setError(false, __LINE__, 1506, get_called_class() . '->' . $method . '()');
  646. }
  647. }