You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

326 lines
7.0 KiB

  1. <?php
  2. namespace Kuxin\Db;
  3. use Kuxin\Config;
  4. use Kuxin\Registry;
  5. class Mysql
  6. {
  7. /**
  8. * 数据库连接ID
  9. *
  10. * @var object
  11. */
  12. public $db_link;
  13. /**
  14. * 事务处理开启状态
  15. *
  16. * @var boolean
  17. */
  18. protected $Transactions;
  19. /**
  20. * 数据库语句
  21. *
  22. * @var array
  23. */
  24. public $sql = '';
  25. /**
  26. * debug开关
  27. *
  28. * @var bool
  29. */
  30. protected $debug;
  31. /**
  32. * PDO操作实例
  33. *
  34. * @var \PDOStatement
  35. */
  36. protected $PDOStatement;
  37. /**
  38. * 构造函数
  39. * 用于初始化运行环境,或对基本变量进行赋值
  40. *
  41. * @param array $params 数据库连接参数,如主机名,数据库用户名,密码等
  42. */
  43. public function __construct(array $params)
  44. {
  45. //连接数据库
  46. $params['charset'] = empty($params['charset']) ? 'utf8' : $params['charset'];
  47. try {
  48. $this->db_link = new \PDO("mysql:host={$params['host']};port={$params['port']};dbname={$params['name']}", $params['user'], $params['pwd'], []);
  49. } catch (\Exception $e) {
  50. trigger_error($e->getMessage());
  51. }
  52. $this->db_link->query("SET NAMES {$params['charset']}");
  53. $this->db_link->query("SET sql_mode='NO_ENGINE_SUBSTITUTION'");
  54. if (!$this->db_link) {
  55. trigger_error($params['driver'] . ' Server connect fail! <br/>Error Message:' . $this->db_link->error() . '<br/>Error Code:' . $this->db_link->errno(), E_USER_ERROR);
  56. }
  57. $this->debug = Config::get('database.debug', Config::get('app.debug', false));
  58. }
  59. /**
  60. * 执行SQL语句
  61. * SQL语句执行函数
  62. *
  63. * @access public
  64. * @param string $sql SQL语句内容
  65. * @return bool
  66. */
  67. public function execute(string $sql, array $bindparams = [])
  68. {
  69. //参数分析
  70. if (!$sql) {
  71. return false;
  72. }
  73. //释放前次的查询结果
  74. if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
  75. $this->free();
  76. }
  77. $this->PDOStatement = $this->db_link->prepare($sql);
  78. foreach ($bindparams as $k => $v) {
  79. $this->PDOStatement->bindValue($k, $bindparams[$k]);
  80. }
  81. $realSql = $this->getRealSql($sql, $bindparams);
  82. if ($this->debug) {
  83. $t = microtime(true);
  84. $result = $this->PDOStatement->execute();
  85. $t = number_format(microtime(true) - $t, 5);
  86. Registry::merge('_sql', $t . ' - ' . $realSql);
  87. } else {
  88. $result = $this->PDOStatement->execute();
  89. }
  90. $this->sql = $realSql;
  91. Registry::setInc('_sqlnum');
  92. return $result;
  93. }
  94. /**
  95. * 获取数据库错误描述信息
  96. *
  97. * @access public
  98. * @return string
  99. */
  100. public function errorInfo()
  101. {
  102. if ($this->PDOStatement) {
  103. $error = $this->PDOStatement->errorInfo();
  104. } else {
  105. $error = $this->db_link->errorInfo();
  106. }
  107. if ($error['0'] == '0000') {
  108. return '';
  109. } else {
  110. return $error['2'];
  111. }
  112. }
  113. /**
  114. * 获取数据库错误信息代码
  115. *
  116. * @access public
  117. * @return int
  118. */
  119. public function errorCode()
  120. {
  121. return $this->PDOStatement->errorCode();
  122. }
  123. /**
  124. * 通过一个SQL语句获取一行信息(字段型)
  125. *
  126. * @access public
  127. * @param string $sql SQL语句内容
  128. * @return mixed
  129. */
  130. public function fetch(string $sql, array $bindParams = [])
  131. {
  132. $result = $this->execute($sql, $bindParams);
  133. if (!$result) {
  134. return false;
  135. }
  136. $myrow = $this->PDOStatement->fetch(\PDO::FETCH_ASSOC);
  137. $this->free();
  138. if (!$myrow)
  139. return null;
  140. return $myrow;
  141. }
  142. /**
  143. * 通过一个SQL语句获取全部信息(字段型)
  144. *
  145. * @access public
  146. * @param string $sql SQL语句
  147. * @return array|mixed
  148. */
  149. public function fetchAll(string $sql, array $bindParams = [])
  150. {
  151. $result = $this->execute($sql, $bindParams);
  152. if (!$result) {
  153. return false;
  154. }
  155. $myrow = $this->PDOStatement->fetchAll(\PDO::FETCH_ASSOC);
  156. $this->free();
  157. if (!$myrow) {
  158. return [];
  159. }
  160. return $myrow;
  161. }
  162. /**
  163. * 获取insert_id
  164. *
  165. * @access public
  166. * @return int
  167. */
  168. public function insertId()
  169. {
  170. return $this->db_link->lastInsertId();
  171. }
  172. /**
  173. * 开启事务处理
  174. *
  175. * @access public
  176. * @return boolean
  177. */
  178. public function startTrans()
  179. {
  180. if ($this->Transactions == false) {
  181. $this->db_link->beginTransaction();
  182. $this->Transactions = true;
  183. }
  184. return true;
  185. }
  186. /**
  187. * 提交事务处理
  188. *
  189. * @access public
  190. * @return boolean
  191. */
  192. public function commit()
  193. {
  194. if ($this->Transactions == true) {
  195. if ($this->db_link->commit()) {
  196. $this->Transactions = false;
  197. }
  198. }
  199. return true;
  200. }
  201. /**
  202. * 事务回滚
  203. */
  204. public function rollback()
  205. {
  206. if ($this->Transactions == true) {
  207. $this->db_link->rollBack();
  208. $this->Transactions = false;
  209. }
  210. }
  211. /**
  212. * 关闭数据库连接
  213. */
  214. public function __destruct()
  215. {
  216. $this->free();
  217. if ($this->db_link == true) {
  218. $this->db_link = null;
  219. }
  220. }
  221. /**
  222. * SQL指令安全过滤
  223. *
  224. * @access public
  225. * @param string $str SQL字符串
  226. * @return string
  227. */
  228. public function quote($str)
  229. {
  230. return $this->db_link->quote($str);
  231. }
  232. /**
  233. * 根据参数绑定组装最终的SQL语句 便于调试
  234. *
  235. * @access public
  236. * @param string $sql 带参数绑定的sql语句
  237. * @param array $bind 参数绑定列表
  238. * @return string
  239. */
  240. public function getRealSql($sql, array $bind = [])
  241. {
  242. foreach ($bind as $key => $val) {
  243. $val = $this->quote($val);
  244. // 判断占位符
  245. $sql = str_replace($key, $val, $sql);
  246. }
  247. return $sql;
  248. }
  249. /**
  250. * 释放查询结果
  251. *
  252. * @access public
  253. */
  254. public function free()
  255. {
  256. $this->PDOStatement = null;
  257. }
  258. /**
  259. * 返回最后插入行的ID或序列值
  260. *
  261. * @return string
  262. */
  263. public function lastInsertId()
  264. {
  265. return $this->db_link->lastInsertId();
  266. }
  267. /**
  268. * 返回受上一个 SQL 语句影响的行数
  269. *
  270. * @return bool|int
  271. */
  272. public function rowCount()
  273. {
  274. if ($this->PDOStatement) {
  275. return $this->PDOStatement->rowCount();
  276. } else {
  277. return false;
  278. }
  279. }
  280. public function lastSql()
  281. {
  282. $sql = $this->sql;
  283. if ($sql) {
  284. return $sql;
  285. } else {
  286. return '没有语句,请执行sql或者开启debug';
  287. }
  288. }
  289. }