1 <?php
2 class mysql{
3 private $host; //主机名称
4
5 private $user; //数据库用户名
6
7 private $pass; //数据库密码
8
9 private $data; //数据库名
10
11 private $conn; //数据库连接标识符
12
13 private $sql; //SQL语句
14
15 private $code; //数据库编码
16
17 private $result; //数据结果集
18
19
20 private $errLog = true; //是否开启错误日志,默认开启
21
22 private $showErr = true; //是否显示所有的错误,具有安全隐患,默认开启
23
24
25 //构造函数,进行类的初始化
26 public function __construct($host,$user,$pass,$data,$code='utf8',$conn='conn'){
27 $this->host = $host;
28
29 $this->user = $user;
30
31 $this->pass = $pass;
32
33 $this->data = $data;
34
35 $this->code = $code;
36
37 $this->conn = $conn;
38
39
40 //对数据库进行初始化连接
41 $this->connect();
42
43 }
44
45
46
47
48 //连接数据库
49 public function connect(){
50 //判断是否为永久连接
51 if($this->conn = 'pconn'){
52 $this->conn = @mysql_pconnect($this->host,$this->user,$this->pass);
53 }else{
54 //临时连接
55 $this->conn = @mysql_connect($this->host,$this->user,$this->pass);
56 }
57
58 //判断是否连接成功
59 if(!$this->conn){
60 $this->show_error('连接服务器失败!');
61 }
62
63 //选择数据库
64 $this->select_db($this->data);
65
66 //设置数据库执行编码
67 $this->query('SET NAMES '.$this->code);
68 }
69
70
71 //选择数据库
72 public function select_db($data){
73 $result = @mysql_select_db($data);
74
75 //如果选择失败
76 if(!$result){
77 $this->show_error('无法连接数据库'.$data);
78 }
79
80 //返回是否连接成功
81 return $result;
82 }
83
84
85 /******************************************************************
86 -- 函数名:query($sql)
87 -- 作 用:数据库执行语句,可执行查询添加修改删除等任何sql语句
88 -- 参 数:$sql sql语句(必填)
89 -- 返回值:布尔
90 -- 实 例:无
91 *******************************************************************/
92
93 public function query($sql){
94 //判断SQL语句是否为空
95 if(empty($sql)){
96 $this->show_error('SQL语句为空!');
97 }
98
99 //两个空格以上的用两个空格代替
100 $this->sql = preg_replace('/ {2,}/',' ',trim($sql));
101
102 //结果集
103 $this->result = mysql_query($sql,$this->conn);
104
105 //判断是否执行成功
106 if(!$this->result){
107 $this->show_error('SQL语句有误',true);
108 }
109
110 //返回结果集
111 return $this->result;
112 }
113
114
115 /******************************************************************
116 -- 函数名:create_db($data)
117 -- 作 用:创建添加新的数据库
118 -- 参 数:$data 数据库名称(必填)
119 -- 返回值:字符串
120 -- 实 例:无
121 *******************************************************************/
122
123 public function create_db($data){
124 $this->query('CREATE DATABASE IF NOT EXISTS `'.$data.'` ');
125 }
126
127
128 //查询服务器下的所有数据库
129 public function show_databases(){
130 $result = $this->query('SHOW DATABASES');
131
132 //定义数组获取结果集
133 $databases = array();
134
135 while($row = mysql_fetch_assoc($result)){
136 $databases[] = $row['Database'];
137 }
138
139 //返回数组
140 return $databases;
141 }
142
143 //查询数据库下所有的表
144 public function show_tables($data=''){
145 //判断是否有传入数据库
146 if(!empty($data)){
147 $data = ' FROM '.$data;
148 }
149
150 $databases = $this->query('SHOW TABLES'.$data);
151
152 //定义数组获取所有的表
153 $tables = array();
154
155 while($row = $this->fetch_array($databases,MYSQL_NUM)){
156 $tables[] = $row[0];
157 }
158
159 //返回数组$tables;
160 return $tables;
161
162 }
163
164 /******************************************************************
165 -- 函数名:get_num_rows($tableName)
166 -- 作 用:获取结果集总数
167 -- 参 数:$tableName 表名称
168
169 -- 返回值:int
170 -- 实 例:无
171 *******************************************************************/
172
173 public function get_num_rows($tableName){
174 //获取表所有字段
175 $fields = $this->get_fields($tableName);
176
177 //拼接SQL语句
178 $sql = "SELECT COUNT('{$fields['pri']}') AS 'total' FROM `{$tableName}`";
179
180 echo $sql;
181
182 //执行SQL语句
183 $result = $this->query($sql);
184
185 $result = $this->fetch_array($result,MYSQL_ASSOC);
186
187 $total = $result['total'];
188
189
190 return $total;
191
192 }
193
194 /******************************************************************
195 -- 函数名:get_fields($tableName)
196 -- 作 用:获取表的所有字段名称
197 -- 参 数:$tableName 新表名(必填)
198 -- 返回值:数组
199 -- 实 例:无
200 *******************************************************************/
201 public function get_fields($tableName){
202 $sql = "DESC {$tableName}";
203
204 $result = $this->query($sql);
205
206 //定义数组存放所有获取到的表字段名称
207 $fields = array();
208
209 while($row = $this->fetch_array($result,MYSQL_ASSOC)){
210 if($row['Key'] == 'PRI'){
211 $fields['pri'] = $row['Field'];
212 }else{
213 $fields[] = $row['Field'];
214 }
215 }
216
217 return $fields;
218
219 }
220
221 /******************************************************************
222 -- 函数名:insert($tableName,$data)
223 -- 作 用:获取表的所有字段名称
224 -- 参 数:$tableName 新表名(必填)
225 $data 需要插入的字段和值的数组
226 键对应的是字段
227 如:$data('name'=>'zhangsan','age'=54);
228 -- 返回值:布尔值
229 -- 实 例:无
230 *******************************************************************/
231
232 public function insert($tableName='',$data=''){
233 //判断用户传递的是否是数组
234 if(!is_array($data)){
235
236 $array = explode(',',$data);
237
238 //定义数组存放字段名和值
239 $data = array();
240
241 foreach($array as $k=>$v){
242 list($key,$value) = explode('=',$v);
243
244 $data[$key] = $value;
245 }
246 }
247
248 //获取这个表的字段结构
249 $table_fields = $this->get_fields($tableName);
250
251 //需要遍历数组中的值,如果对应的字段存在才插入表中
252 foreach($data as $k=>$v){
253 if(in_array($k,$table_fields)){
254 //拼接要插入的字段
255 $_fields .= $k.',';
256
257 //拼接要插入的值
258 $_values .= "'".$v."'".',';
259 }
260 }
261
262 //需要将插入字段右边边多余的,去除
263 $_fields = rtrim($_fields,',');
264
265 //需要将插入的值右边多余的,去除
266 $_values = rtrim($_values,',');
267
268 //拼装SQL语句
269 $sql = "INSERT INTO {$tableName} ({$_fields}) VALUES ($_values)";
270
271 //执行SQL语句
272 $this->query($sql);
273
274 //返回受影响的行数
275 return $this->affected_rows();
276
277
278
279 }
280
281 /******************************************************************
282 -- 函数名:delete($tableName,$where)
283 -- 作 用:删除指定的数据
284 -- 参 数:$tableName 表名(必填)
285 $where 删除条件
286 -- 返回值:int 受影响的行数
287 -- 实 例:无
288 *******************************************************************/
289 public function delete($tableName,$where){
290 //判断删除条件是否为空
291 if(empty($where)){
292 $this->show_error("请指定删除条件!");
293 }
294
295 //拼接SQL语句
296 $sql = "DELETE FROM `{$tableName}` WHERE {$where}";
297
298 //执行SQL语句
299 $this->query($sql);
300
301 //返回受影响的行数
302 return $this->affected_rows();
303
304
305 }
306
307 /******************************************************************
308 -- 函数名:update($tableName,$data,$where)
309 -- 作 用:更新指定的数据
310 -- 参 数:$tableName 表名(必填)
311 $data 要更新的字段和值
312 $where 更新的条件
313 -- 返回值:int 受影响的行数
314 -- 实 例:无
315 *******************************************************************/
316 public function update($tableName,$data,$where){
317 //判断是否有指定更新条件
318 if(empty($where)){
319 $this->show_error("未指定更新条件!");
320 }
321
322 //判断用户传入的更新是否是数组
323 if(!is_array($data)){
324
325 $array = explode(',',$data);
326
327 //定义数组获取字段名称和值
328 $data = array();
329
330
331 foreach($array as $v){
332 list($key,$value) = explode('=',$v);
333
334 //将获取到的键和值存入数组
335 $data[$key] = $value;
336 }
337 }
338
339 //获取表的所有字段
340 $fields = $this->get_fields($tableName);
341
342 //开始遍历数组,并检查数据表中是否存在该字段
343 foreach($data as $k=>$v){
344 if(in_array($k,$fields)){
345 $_fields .= $k."='".$v."',";
346 }
347 }
348
349 //去掉拼接值右边多余的,号
350 $_fields = rtrim($_fields,',');
351
352 //拼接SQL语句
353 $sql = "UPDATE `{$tableName}` SET {$_fields} WHERE {$where}";
354
355 //执行SQL语句
356 $this->query($sql);
357
358 //返回受影响的行数
359 return $this->affected_rows();
360
361
362 }
363
364
365 /******************************************************************
366 -- 函数名:last_insert_id()
367 -- 作 用:获取表中最后插入的ID号
368 -- 参 数:
369 -- 返回值:int
370 -- 实 例:无
371 *******************************************************************/
372 public function last_insert_id(){
373 return mysql_insert_id($this->conn);
374 }
375
376
377 /******************************************************************
378 -- 函数名:affected_rows()
379 -- 作 用:返回结果集执行后受影响的行数
380 -- 参 数:
381 -- 返回值:布尔值
382 -- 实 例:无
383 *******************************************************************/
384 public function affected_rows() {
385 return mysql_affected_rows($this->conn);
386 }
387
388 /******************************************************************
389 -- 函数名:copy_tables($tb1,$tb2,$where)
390 -- 作 用:复制表
391 -- 参 数:$tb1 新表名(必填)
392 $tb2 待复制表的表名(必填)
393 $type 复制条件(选填) 1.表示复制结构和内容,默认 2.表示复制结构
394 -- 返回值:布尔
395 -- 实 例:无
396 *******************************************************************/
397 public function copy_tables($table1,$table2,$type=1){
398 if(empty($table1)){
399 $this->show_error('请填写新表名称!');
400 }
401
402 if(empty($table2)){
403 $this->show_error('请填写要复制的表名称!');
404 }
405
406 switch($type){
407 case 1:
408 $sql = "CREATE TABLE `{$table1}` SELECT * FROM `{$table2}`";
409
410 $this->query($sql);
411
412 break;
413
414 case 2:
415 $sql = "create TABLE `{$table1}` SELECT * FROM `{$table2}` WHERE 1=2";
416
417 $this->query($sql);
418
419 break;
420
421 default:
422 $sql = "CREATE TABLE `{$table1}` SELECT * FROM `{$table2}`";
423
424 $this->query($sql);
425
426 break;
427 }
428
429 }
430
431 /*****************************************************************
432 --函数名:drop_table($tableName)
433 --作 用:从数据库中删除某张表
434 --参 数:$tableName 要删除的表名称
435 --返回值:布尔
436 --实 例:$DB->drop_table('user');
437 *****************************************************************/
438 public function drop_table($tableName){
439 $result = $this->query("DROP TABLE IF EXISTS {$tableName}");
440
441 var_dump($result);
442 }
443
444
445 /*****************************************************************
446 --函数名:select($table,$fields,$where,$order,$limit)
447 --作 用:从表中查询数据,并返回结果集
448 --参 数:$table 查询的表名称
449 $fields 查询的字段名称
450 $where 查询的字段名称
451 $limit 查询多少条
452 --返回值:布尔
453 --实 例:$DB->drop_table('user','*','id>20','20');
454 *****************************************************************/
455 public function select($table,$fields="",$where="",$order="",$limit=""){
456 //获取表结构
457 $_fields = $this->get_fields($table);
458
459 $fields = empty($fields) ? '*' : $fields;
460
461 $where = empty($where) ? "" : "WHERE {$where}";
462
463 $limit = empty($limit) ? "" : "LIMIT {$limit}";
464
465 $order = empty($order) ? "ORDER BY {$_fields['pri']}" : "ORDER BY {$order}";
466
467 $sql = "SELECT {$fields} FROM `{$table}` {$where} {$order} {$limit}";
468
469 echo $sql;
470 return $this->query($sql);
471 }
472
473
474 /******************************************************************
475 -- 函数名:fetch_array($Table,$Condition)
476 -- 作 用:根据从结果集取得的行生成关联数组
477 -- 参 数:$result 结果集(选填)
478 $type 数组类型,可以接受以下值:MYSQL_ASSOC,MYSQL_NUM 和 MYSQL_BOTH(选填)
479 -- 返回值:布尔
480 -- 实 例:$DB->Del('mydb','id=1')
481 *******************************************************************/
482
483 public function fetch_array($result='',$type="MYSQL_BOTH"){
484 if(empty($result)){
485 $result = $this->result;
486 }
487
488 //如果结果集不存在
489 if(!$result){
490 $this->show_error("未获取大查询结果集",true);
491 }
492
493 //echo $type;
494
495 return mysql_fetch_array($result,$type);
496 }
497
498
499 /******************************************************************
500 -- 函数名:get_info($num)
501 -- 作 用:取得 MySQL 服务器信息
502 -- 参 数:$num 信息值(选填)
503 -- 返回值:字符串
504 -- 实 例:无
505 *******************************************************************/
506 public function get_info($num){
507 switch($num){
508 //获取mysql服务器信息
509 case 1:
510 return mysql_get_server_info();
511
512 break;
513
514 //获取mysql主机信息
515 case 2:
516 return mysql_get_host_info();
517
518 break;
519
520 //获取mysql协议信息
521 case 3:
522 return mysql_get_proto_info();
523
524 break;
525
526 default:
527 return mysql_get_client_info();
528
529 break;
530 }
531 }
532
533
534
535 //获取客户端的真实IP地址
536 public function getip(){
537 if($_SERVER['HTTP_X_FORWARDED_FOR']){
538 return $_SERVER['HTTP_X_FORWARDED_FOR'];
539 }elseif($_SERVER['HTTP_CLIENT_IP']){
540 return $_SERVER['HTTP_CLIENT_IP'];
541 }elseif($_SERVER['REMOTE_ADDR']){
542 return $_SERVER['REMOTE_ADDR'];
543 }elseif(getenv('HTTP_X_FORWARDED_FOR')){
544 return getenv('HTTP_X_FORWARDED_FOR');
545 }elseif(getenv('HTTP_CLIENT_IP')){
546 return getenv('HTTP_CLIENT_IP');
547 }elseif(getenv('REMOTE_ADDR')){
548 return getenv('REMOTE_ADDR');
549 }
550
551 //如果没有获取到IP返回null
552 return null;
553 }
554
555
556 /******************************************************************
557 -- 函数名:show_error($message,$sql)
558 -- 作 用:输出显示错误信息
559 -- 参 数:$msg 错误信息(必填)
560 $sql 显示错误的SQL语句,在SQL语句错误时使用(选填)
561 -- 返回值:字符串
562 -- 实 例:无
563 *******************************************************************/
564
565 public function show_error($msg='',$sql=false){
566 $err = '['.mysql_errno().']'.mysql_error();
567
568 if($sql){
569 $sql = 'SQL语句:'.$this->sql;
570 }
571
572 //开启了错误日志记录后
573 if($this->errLog){
574 //定义错误日志存放目录
575 $dirs = 'error/';
576
577 //错误日志的名称
578 $fileName = date('Y-m-d').'.log';
579
580 //拼接路径
581 $filePath = $dirs.$fileName;
582
583 //判断路径是否存在
584 if(!is_dir($dirs)){
585 $dirs = explode('/',$dirs);
586
587 $temp = '';
588
589 foreach($dirs as $dir){
590 $temp .= $dir.'/';
591
592 if(!is_dir($temp)){
593 mkdir($temp,0777) or die('__无法建立目录'.$temp.',自动取消记录错误信息');
594 }
595 }
596
597 $filePath = $temp.$fileName;
598 }
599
600 $text="错误事件:".$msg."\r\n错误原因:".$err."\r\n".($sql?$sql."\r\n":'')."客户端IP:".$this->getip()."\r\n记录时间:".date('Y-m-d H:i:s')."\r\n\r\n";
601
602 $log='错误日志:__'.(error_log($text,3,$filePath)?'此错误信息已被自动记录到日志'.$fileName:'写入错误信息到日志失败');
603
604
605 //如果有开启显示错误日志
606 if($this->showErr){
607 echo '
608 <fieldset class="errlog">
609 <legend>错误信息提示</legend>
610 <label class="tip">错误事件:'.$err.'</label>
611 <label class="msg">错误原因: '.$msg.'</label>
612 <label class="sql">'.$sql.'</label>
613 <label class="log">'.$log.'</label>
614 </fieldset>';
615
616 //终止程序运行
617 exit();
618
619 }
620
621
622 }
623
624 }
625
626
627 //释放结果集
628 public function free(){
629 mysql_free_result($this->result);
630 }
631
632 //关闭数据库连接
633 public function close(){
634 mysql_close($this->conn);
635 }
636
637
638 //析构函数
639 public function __desctruct(){
640 $this->free();
641
642 $this->close();
643 }
644
645
646
647
648
649
650
651 }
652
653
654 ?>