Base.php 16 KB

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