管理系统的操做日志如何作成通用的模块一直是个让我头疼的问题,不过看了博客园里的某篇文章后,如今基本解决了。php
相关文章连接:《系统操做日志设计》html
在开始作以前,必须把两个日志分清楚,那就是普通操做日志和业务操做日志,这二者有何区别?sql
在我理解,普通操做日志就是单表的操做记录,而业务操做日志则就是一系列的普通操做日志的集合。数据库
打个比方,用户须要购买同样宝贝,已经到了下单那步,下单就是个业务,这个业务背后就是一系列的业务,如:fetch
生成订单 → 生成商品快照 → 发送一条站内信 → 删除购物车里对应宝贝优化
这样一个下单操做就包含了4部分,能够把这4部分当作是4张表,分别对这4张表进行对应的操做,就实现了业务。this
但今天我要讲的不是业务操做日志,由于不一样项目的业务不尽相同,因此它没法作成通用模块,而我要讲的,就是普通操做日志。spa
上面解释了一大段,下面干货就要亮相了,先洗把脸清醒下。设计
……日志
首先,哪些地方须要记录操做日志?执行insert、update、delete这3个操做的时候,就须要进行日志,而日志执行的前后顺序以下
insert | 在insert后执行 |
update | 在update先后都要执行,操做前获取操做前数据,操做后获取操做后数据 |
delete | 在delete前执行 |
顺序清楚后,就来看下我写的一份日志操做类吧,初版随便写写的,重复代码有点多,还将来得及优化。
class LOG{ protected $primaryid; protected $tbid; protected $tbname; protected $keys; protected $values; /** * 参数说明 * int $tbid 查询指定表的id * string $tbname 数据库表名 */ public function insert($tbid, $tbname){ global $db; //查询表注释 $db->query('show table status where name = "'.$tbname.'"'); $tb = $db->fetch(); //插入日志主表 $returnid = $db->insert(0, 2, 'tb_log', array( 'adminid = '.$_SESSION['admin']['id'], 'type = 1', 'tableid = '.$tbid, 'tablename = "'.$tbname.'"', 'comment = "'.$tb['Comment'].'"', 'dt = now()' )); //查询字段注释 $db->query('show full columns from '.$tbname); $tb = $db->fetchAll(); foreach($tb as $v){ $commentArray[$v['Field']] = $v['Comment']; } //查询全部字段信息,插入日志从表 $rs = $db->select(0, 1, $tbname, '*', 'and tbid = '.$tbid); $keys = array_keys($rs); $values = array_values($rs); for($i = 0; $i < count($keys); $i++){ $db->insert(0, 0, 'tb_log_content', array( 'logid = '.$returnid, 'tbkey = "'.$keys[$i].'"', 'tbvalue = "'.$values[$i].'"', 'comment = "'.$commentArray[$keys[$i]].'"' )); } } public function updateStart($tbid, $tbname){ global $db; //查询表注释 $db->query('show table status where name = "'.$tbname.'"'); $tb = $db->fetch(); //插入日志主表 $returnid = $db->insert(0, 2, 'tb_log', array( 'adminid = '.$_SESSION['admin']['id'], 'type = 2', 'tableid = '.$tbid, 'tablename = "'.$tbname.'"', 'comment = "'.$tb['Comment'].'"', 'dt = now()' )); //查询修改前数据信息 $rs = $db->select(0, 1, $tbname, '*', 'and tbid = '.$tbid); $keys = array_keys($rs); $values = array_values($rs); $this->primaryid = $returnid; $this->tbid = $tbid; $this->tbname = $tbname; $this->keys = $keys; $this->values = $values; } public function updateEnd(){ global $db; //查询字段注释 $db->query('show full columns from '.$this->tbname); $tb = $db->fetchAll(); foreach($tb as $v){ $commentArray[$v['Field']] = $v['Comment']; } //查询修改后数据信息 $rs = $db->select(0, 1, $this->tbname, '*', 'and tbid = '.$this->tbid); $currentvalues = array_values($rs); //先后信息进行比较 for($i = 0; $i < count($currentvalues); $i++){ if($this->values[$i] !== $currentvalues[$i]){ $db->insert(0, 0, 'tb_log_content', array( 'logid = '.$this->primaryid, 'tbkey = "'.$this->keys[$i].'"', 'tbvalue = "'.$this->values[$i].'"', 'currenttbvalue = "'.$currentvalues[$i].'"', 'comment = "'.$commentArray[$this->keys[$i]].'"' )); } } } public function delete($tbid, $tbname){ global $db; //查询表注释 $db->query('show table status where name = "'.$tbname.'"'); $tb = $db->fetch(); //插入日志主表 $returnid = $db->insert(0, 2, 'tb_log', array( 'adminid = '.$_SESSION['admin']['id'], 'type = 3', 'tableid = '.$tbid, 'tablename = "'.$tbname.'"', 'comment = "'.$tb['Comment'].'"', 'dt = now()' )); //查询字段注释 $db->query('show full columns from '.$tbname); $tb = $db->fetchAll(); foreach($tb as $v){ $commentArray[$v['Field']] = $v['Comment']; } //查询全部字段信息,插入日志从表 $rs = $db->select(0, 1, $tbname, '*', 'and tbid = '.$tbid); $keys = array_keys($rs); $values = array_values($rs); for($i = 0; $i < count($keys); $i++){ $db->insert(0, 0, 'tb_log_content', array( 'logid = '.$returnid, 'tbkey = "'.$keys[$i].'"', 'tbvalue = "'.$values[$i].'"', 'comment = "'.$commentArray[$keys[$i]].'"' )); } } }
使用前,须要引入数据库操做类,这是我以前写的一份,可参考《全新的PDO数据库操做类(仅适用Mysql)》。
引入以后,就能够开始使用了。
select
1
|
$log
->insert(82,
'tb_member'
);
|
update
1
2
3
|
$log
->updateStart(82,
'tb_member'
);
//中间放更新操做代码
$log
->updateEnd();
|
delete
1
|
$log
->
delete
(82,
'tb_member'
);
|
能够看到,一共只须要两个参数便可,分别是表ID(主键)和表名称。
另外须要强调一点,表注释和字段注释必定要完整,由于记录的信息包含注释,目的就是为了查阅的时候能清楚哪一个字段是干什么用的。
下面就看下成品吧
最后把表结构分享下,一共2张表,一张主表一张从表,主表记录操做表及操做人等信息,从表记录操做的表字段信息。
-- ---------------------------- -- Table structure for `tb_log` -- ---------------------------- CREATE TABLE `tb_log` ( `tbid` bigint(20) NOT NULL AUTO_INCREMENT, `adminid` bigint(20) DEFAULT NULL COMMENT '管理员id', `type` tinyint(4) DEFAULT '1' COMMENT '操做类型:1新增2修改3删除', `tableid` bigint(20) DEFAULT NULL, `tablename` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '表名', `comment` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `dt` datetime DEFAULT NULL, PRIMARY KEY (`tbid`) ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Table structure for `tb_log_content` -- ---------------------------- CREATE TABLE `tb_log_content` ( `tbid` bigint(20) NOT NULL AUTO_INCREMENT, `logid` bigint(20) DEFAULT NULL, `tbkey` longtext COLLATE utf8_unicode_ci, `tbvalue` longtext COLLATE utf8_unicode_ci, `currenttbvalue` longtext COLLATE utf8_unicode_ci, `comment` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`tbid`) ) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;