分享一个mysql类~

 
  1. <?php
  2. /**
  3. * 操作mysql 的基础类,其它与mysql有关的类都继承于此基类
  4. *
  5. * 此class中的$table都是已经包含表前缀的完整表名
  6. *
  7. * ver 20090717
  8. * 使用范例
  9. * $db = new DB('localhost','root','password','database','utf8');
  10. * $db->debug = true;
  11. * $db->primaryKeys = array (
  12. * 'table_1' => 'id',
  13. * 'table_2' => 'id2'
  14. * );
  15. * $db->find('table_1', 1);
  16. * $db->findAll('table_2', '*', 'catid=1', 'id desc');
  17. * ……
  18. */
  19. class DBBase extends Base {
  20. public $debug; //调试
  21. public $primaryKeys = array(); //设定各表的主键,在创建类实例后必须设定表主键 $db->primaryKeys(array('表1'=>'主键字段 1','表2'=>'主键字段2'))
  22. public $queryCount = 0;
  23. public $haltOnError = true;
  24. public $displayError=true;
  25. public $queryID;
  26. public $connected = false;
  27. public $tableFields = array();
  28. public $dbhost;
  29. public $dbuser;
  30. public $dbpwd;
  31. public $dbname;
  32. public $dbcharset;
  33. public $pconnect = false;
  34. public function __construct($host, $user, $pwd, $database = null, $charset = null, $pconnect = null) {
  35. $this->dbhost = $host;
  36. $this->dbuser = $user;
  37. $this->dbpwd = $pwd;
  38. $this->dbname = $database;
  39. $this->dbcharset = $charset;
  40. $this->pconnect = $pconnect;
  41. }
  42. public public function connect()
  43. {
  44. if ($this->pconnect) {
  45. @mysql_pconnect($this->dbhost, $this->dbuser, $this->dbpwd) || die('<b>MySQL ERROR:</b> ' . mysql_error());
  46. } else {
  47. @mysql_connect($this->dbhost, $this->dbuser, $this->dbpwd) || die('<b>MySQL ERROR:</b> ' . mysql_error());
  48. }
  49. if ($this->dbname != null) {
  50. $this->selectdb($this->dbname);
  51. }
  52. $this->connected = true;
  53. }
  54. public function selectdb($dbname) {
  55. $this->dbname = $dbname;
  56. mysql_select_db($this->dbname) || die('<b>MySQL ERROR(mysql_selectt_db):</b> ' . mysql_error());
  57. $serverVersion=$this->serverVersion();
  58. if ($this->dbcharset && $this->serverVersion()>='4.1') {
  59. mysql_query("SET NAMES " . $this->dbcharset) || die('<b>MySQL ERROR:</b> ' . mysql_error());
  60. }
  61. }
  62. /**
  63. * 查询 MYSQL版本,以确定是否要用set names xxx
  64. *
  65. * @return unknown
  66. */
  67. private function serverVersion()
  68. {
  69. $qid=mysql_query('select version()');
  70. $row=mysql_fetch_array($qid);
  71. return $row[0];
  72. }
  73. /**
  74. * 运行sql语句
  75. *
  76. */
  77. public function query($sql)
  78. {
  79. if ($this->debug) {
  80. echo "<p><b>MySQL DEBUG:</b> $sql</p>";
  81. }
  82. if (!$this->connected) {
  83. $this->connect();
  84. }
  85. $this->queryID = @mysql_query($sql);
  86. if (!$this->queryID) {
  87. if ($this->displayError) {
  88. echo '<p><b>MySQL DEBUG:</b> ' . $sql . '</p>';
  89. echo '<p><b>MySQL ERROR:(' . mysql_errno() . ')</b> ' . mysql_error() . '</p>';
  90. }
  91. $this->haltOnError && die("/nmySQL error and session halted/n");
  92. }
  93. $this->queryCount++;
  94. return $this->queryID;
  95. }
  96. /**
  97. * 构建select语句
  98. *
  99. * @param string $table
  100. * @param array $fields
  101. * @param string|int $conditions
  102. * @param string $sort
  103. * @param int $limit
  104. * @return string
  105. */
  106. public function buildSelectSQL($table, $fields, $conditions, $sort, $limit)
  107. {
  108. $sql = "SELECT " . self::qfield($table, $fields) . " FROM `$table`";
  109. if (!empty($conditions)) {
  110. if (is_int($conditions) || (int)$conditions) {
  111. $sql .= ' WHERE ' . $this->primaryKeys[$table] . " = '" . self::qstr($conditions) . "'";
  112. } else {
  113. $sql .= " WHERE $conditions";
  114. }
  115. }
  116. if ($sort) {
  117. $sql .= " ORDER BY $sort";
  118. }
  119. if ($limit) {
  120. $sql .= " LIMIT $limit";
  121. }
  122. return $sql;
  123. }
  124. /**
  125. * 构建insert into 语句
  126. *
  127. * @param string $table
  128. * @param array $row
  129. * @return string
  130. */
  131. public function buildInsertSQL($table, $row)
  132. {
  133. $fields = self::getTableFields($table);
  134. foreach ($row as $k=>$v) {
  135. if (isset($fields[$k])) {
  136. $sqlrow[$k] = "'" . $this->qstr($v) . "'" ;
  137. }
  138. }
  139. $sql = "INSERT INTO `$table` (" . $this->qfield($table, array_keys($sqlrow)) . ") VALUES (".
  140. join(",", $sqlrow) . ");/n";
  141. return $sql;
  142. }
  143. /**
  144. * 构建 update 语句
  145. *
  146. * @param string $table
  147. * @param array $row
  148. * @return string
  149. */
  150. public function buildUpdateSQL($table, $row, $condition)
  151. {
  152. $fields = self::getTableFields($table);
  153. $sql = "UPDATE `$table` SET ";
  154. foreach ($row as $k=>$v) {
  155. if (isset($fields[$k]) && $k != $this->primaryKeys[$table]) {
  156. $sql .= "`$k` = '" . $this->qstr($v) . "'," ;
  157. }
  158. }//foreach
  159. $sql = substr($sql, 0, strlen($sql)-1) . ' WHERE 1';
  160. if (isset($row[$this->primaryKeys[$table]])) {
  161. $sql .= " AND " . $this->primaryKeys[$table] . " = '" .
  162. $this->qstr($row[$this->primaryKeys[$table]]) . "'";
  163. }
  164. if ($condition) {
  165. $sql .= " AND $condition";
  166. }
  167. return $sql;
  168. }
  169. /**
  170. * 构建delete语句
  171. *
  172. * @param string $table
  173. * @param string $conditions
  174. * @param int $limit
  175. * @return string
  176. */
  177. public function buildDeleteSQL($table, $conditions, $limit = null)
  178. {
  179. $sql = "DELETE FROM $table";
  180. if ($conditions) {
  181. if (is_int($conditions) || (int)$conditions) {
  182. $sql .= " WHERE " . $this->primaryKeys[$table] . " = '" . $this->qstr($conditions) . "'";
  183. } else {
  184. $sql .= " WHERE $conditions";
  185. }
  186. }//if $conditions
  187. if ($limit) {
  188. $sql .= " LIMIT " . (int)$limit;
  189. }
  190. return $sql;
  191. }
  192. //转义相关字符
  193. public function qstr($str, $addComma = false)
  194. {
  195. if (!$this->connected) {
  196. $this->connect();
  197. $this->connected = true;
  198. }
  199. $result = mysql_real_escape_string($str);
  200. if ($addComma) {
  201. $result = "'".$result."'";
  202. }
  203. return $result;
  204. }
  205. //私有方法,格式化字段,将 field 变为 `table`.`field`
  206. private function qfield($table, $fields)
  207. {
  208. $table = "`$table`.";
  209. !$fields && $fields = '*';
  210. if ('*' != $fields) {
  211. if (!is_array($fields)) {
  212. $fields = explode(',', $fields);
  213. }
  214. foreach ($fields as $field) {
  215. $field = trim($field);
  216. if (!preg_match('//s/', $field)) {
  217. $result[] = $table . '`' . $field . '`';
  218. } else {
  219. $result[] = $table . $field;
  220. }
  221. }
  222. } else {
  223. $result[] = $table . $fields;
  224. }
  225. return join(',', $result);
  226. }
  227. /**
  228. * 查找单条数据
  229. *
  230. * @param string $table 表名
  231. * @param array/sring $fields 查询字段
  232. * @param string/int $conditions 查询条件。当为数值时,就是查询表主键值
  233. * @param string $sort 排序方法
  234. * @return array
  235. */
  236. public function find ($table, $fields= '*', $conditions=null, $sort=null)
  237. {
  238. $sql = self::buildSelectSQL($table, $fields, $conditions, $sort, 1);
  239. return self::findBySql($sql);
  240. }
  241. /**
  242. * 查询多条数据
  243. *
  244. * @param string $table
  245. * @param string $fields
  246. * @param string/int $conditions
  247. * @param string $sort
  248. * @param int $limit 限制查询数据条数
  249. * @param int $page 分页 查询时设定第N页,分布查询请使用findPage()
  250. * @return 多维数组
  251. */
  252. public function findAll ($table, $fields= '*', $conditions=null, $sort=null, $limit=null, $page=null)
  253. {
  254. if ($limit) {
  255. $limit = (int)$limit;
  256. }
  257. if ($limit && $page) {
  258. $limit = (int)$limit * (int)$page . ',' . (int)$limit;
  259. }
  260. $sql = self::buildSelectSQL($table, $fields, $conditions, $sort, $limit);
  261. return self::findAllBySql($sql);
  262. }
  263. /**
  264. * 分页查找
  265. *
  266. * @param string $table
  267. * @param string $fields
  268. * @param string $conditions
  269. * @param string $sort
  270. * @param int $page 第N页
  271. * @param int $pagesize 每页返回的数量数
  272. * @return 多维数组
  273. */
  274. public function findPage ($table, $fields= '*', $conditions=null, $sort=null, $page, $pagesize)
  275. {
  276. (int)$page < 1 && $page=1;
  277. $limit = (int)$pagesize * ((int)$page - 1) . ',' . (int)$pagesize;
  278. $sql = self::buildSelectSQL($table, $fields, $conditions, $sort, $limit);
  279. $sqlpage = preg_replace('/^/s*SELECT/s.*/s+FROM/s/Uis','SELECT COUNT(*) as c FROM ',
  280. self::buildSelectSQL($table, $fields, $conditions, $sort, null));
  281. $c = self::findBySql($sqlpage);
  282. $result['count'] = $c['c'];
  283. $result['rowset'] = self::findAllBySql($sql);
  284. $result['pagecount'] = ceil($result['count'] / $pagesize);
  285. return $result;
  286. }
  287. /**
  288. * 返回符合条件的数据数
  289. *
  290. * @param string $table
  291. * @param string $conditions
  292. * @return int
  293. */
  294. public function findCount($table, $conditions)
  295. {
  296. $row = self::findBySql("SELECT COUNT(*) AS c FROM $table WHERE $conditions");
  297. return $row['c'];
  298. }
  299. /**
  300. * 直接使用SQL语句查询,返回单条数据,不会自动处理表前缀、字符转义等工作
  301. *
  302. * @param string $sql
  303. * @return 返回一维数组
  304. */
  305. public function findBySql ($sql)
  306. {
  307. $r = mysql_fetch_assoc($this->query($sql));
  308. mysql_free_result($this->queryID);
  309. return $r;
  310. }
  311. /**
  312. * 直接使用SQL语句查询,返回多条数据,不会自动处理表前缀、字符转义等工作
  313. *
  314. * @param string $sql
  315. * @return array
  316. */
  317. public function findAllBySql ($sql)
  318. {
  319. self::query($sql);
  320. while( $row = mysql_fetch_assoc($this->queryID)) {
  321. $rows[] = $row;
  322. }
  323. mysql_free_result($this->queryID);
  324. return $rows;
  325. }
  326. /**
  327. * 创建(插入)一条数据,会自动分析数组$row中的键值,过滤表字段中不存在的键值
  328. *
  329. * @param string $table
  330. * @param array $row �多维数组
  331. * @return 数据表中�返回插入的主键值
  332. */
  333. public function create($table, $row)
  334. {
  335. self::query($this->buildInsertSQL($table,$row));
  336. return mysql_insert_id();
  337. }
  338. /**
  339. * 更新单条数据,会自动分析数组$row中的键值,过滤表字段中不存在的键值
  340. *
  341. * @param string $table
  342. * @param array $row
  343. * @param string $conditions
  344. * @return 返回数据表受影响的行数
  345. */
  346. public function update($table,$row,$conditions=null)
  347. {
  348. self::query(self::buildUpdateSQL($table, $row, $conditions));
  349. return mysql_affected_rows();
  350. }
  351. /**
  352. * 根据$row数组中是否含有表主键值来创建或更新数据,
  353. * $row中含有表主键值执行update()操作,反之执行create()操作,是create()与update()的结合体
  354. * 会自动分析数组$row中的键值,过滤表字段中不存在的键值
  355. * @param string $table
  356. * @param array $row
  357. * @param string $conditions
  358. * @return 根据是创建还是更新返回数据表插入的主键值或受影响的行数
  359. */
  360. public function save($table, $row, $conditions=null)
  361. {
  362. if (isset($row[$this->primaryKeys[$table]])) {
  363. return self::update($table, $row, $conditions);
  364. } else {
  365. return self::create($table, $row);
  366. }
  367. }
  368. /**
  369. * 删除符合条件的数
  370. *
  371. * @param string $table
  372. * @param string $conditions
  373. * @param int $limit 限制删除数据的数组
  374. * @return 返回删除后受影响的行数
  375. */
  376. public function delete($table, $conditions, $limit = null)
  377. {
  378. self::query($this->buildDeleteSQL($table, $conditions, $limit));
  379. return mysql_affected_rows();
  380. }
  381. //私有方法,获取表中字段的信息,返回多维数组
  382. protected function getTableFields($table)
  383. {
  384. if (!isset($this->tableFields[$table])) {
  385. // $table = $this->tablePrefix . $table;
  386. $table = $table;
  387. $sql = "DESCRIBE $table";
  388. $rows = self::findAllBySql($sql);
  389. foreach ((array)$rows as $row) {
  390. $result[$row['Field']] = $row;
  391. }
  392. $this->tableFields[$table] = $result;
  393. }
  394. return $this->tableFields[$table];
  395. }
  396. /*备份数据库 ,参数$tables如果手工设定地话,不需要给出表前缀
  397. $bakfile可以不指定(备份在PHP 程序 同一目录 下),也可以是一个目录(自动生成个文件 名备份在此目录下),也可以是一个包含路径的文件名
  398. */
  399. public function backup($bakfile = null, $tables = array())
  400. {
  401. if (empty($bakfile)) {
  402. $bakfile = $this->dbname . date("Ymdhis") . '.sql';
  403. } elseif (is_dir($bakfile)) {
  404. if (preg_match('///$/', $bakfile)) {
  405. $bakfile = $bakfile . $this->dbname . date("Ymdhis") . '.sql';
  406. } else {
  407. $bakfile = $bakfile . '/' . $this->dbname . date("Ymdhis") . '.sql';
  408. }
  409. }
  410. if (!$tables) {
  411. $this->query("SHOW TABLES");
  412. while ($row = mysql_fetch_row($this->queryID)) {
  413. $tables[] = $row[0];
  414. }
  415. } else {
  416. foreach ($tables as $k => $v) {
  417. $tables[$k] = $this->tablePrefix . $v;
  418. }
  419. }
  420. if ($fp = fopen($bakfile, 'wb')) {
  421. if ($this->dbcharset) {
  422. fwrite($fp, "SET NAMES " . $this->dbcharset . ";/n/n");
  423. }
  424. foreach ($tables as $table) {
  425. $this->dumpTable($table, $fp);
  426. fwrite($fp, "/n");
  427. }//foreach
  428. fclose($fp);
  429. return true;
  430. } else {
  431. return false;
  432. }//if
  433. }
  434. //私有方法 导出表格
  435. protected function dumpTable($table, $fp)
  436. {
  437. //备份表结构
  438. //fwrite($fp, "-- /n-- {$table}/n-- /n");
  439. $row = $this->findBySql("SHOW CREATE TABLE `{$table}`");
  440. fwrite($fp, str_replace("/n","", $row['Create Table']) . ";/n/n" );
  441. //备份表库数据
  442. $this->query("SELECT * FROM `{$table}`");
  443. while ($row = mysql_fetch_assoc($this->queryID)) {
  444. foreach ($row as $k=>$v) {
  445. $row[$k] = "'" . $this->qstr($v) . "'" ;
  446. }
  447. $sql = "INSERT INTO `$table` VALUES (" . join(",", $row) . ");/n";
  448. fwrite($fp, $sql);
  449. }
  450. mysql_free_result($this->queryID);
  451. fwrite($fp, "/n");
  452. }
  453. //恢复数据库文件
  454. public function restore($bakfile)
  455. {
  456. if ($fp = fopen($bakfile, 'r')) {
  457. $sql = '';
  458. while (!feof($fp)) {
  459. $line = fgets($fp);
  460. if (strpos($line,'--')!==0)
  461. {
  462. $sql .= $line;
  463. //pp($sql);
  464. }
  465. if (preg_match('/;/s*$/', $sql)) {
  466. $this->query($sql);
  467. $sql = '';
  468. }
  469. }
  470. fclose($fp);
  471. return true;
  472. } else {
  473. return false;
  474. }
  475. }
  476. }//class
  477. ?>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值