ThinikPhp 将数据库模型的增、删、改操作写入日志
- 记录增、删、改等操作到日志系统
- 定义一些大部分数据库都需要验证的规则(子类可覆盖或自定义)或者需要自动生成的字段(如每个数据库都有一个记录当前时间的字段create_time)
<?php
/* *
* 公共模型
*/
namespace Common\Model;
use Think\Model;
class CommonModel extends Model {
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 12:22:19
* @Description: 验证字段,子类可以覆盖或移出
*/
protected $_validate = array(
array('code','require','{%ERROR_NOT_PAST}'),//必须
array('name','require','{%ERROR_NOT_PAST}'),//必须
);
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 12:08:38
* @Description: 所有继承的子类字段create_time自动生成当前时间
*/
protected $_auto = array (
array ('create_time', 'mGetDate', 1, 'callback' ), // 增加的时候调用回调函数
);
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 15:52:40
* @Description: 返回该类的自动验证信息,用于在子类中合并该验证信息(不能在子类中定义此$_validate属性否则会被覆盖,如果不需要在子类中合并则可以可忽略此方法)
*/
protected function get_validate()
{
return $this->_validate;
}
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 12:06:03
* @Description: 获取当前时间
*/
protected function mGetDate() {
return date ( 'Y-m-d H:i:s' );
} /**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 10:50:20
* @Description: 更新成功后的回调方法
*/
protected function _after_update($data,$options) {
//区分会员登录和更改操作
if( $options['model']=="Users"
&& $data['last_login_ip']
&& $data['last_login_time']
&& count($data)==3
)
{
$this->after_write("login",$data,$options);
}
else{
$this->after_write("update",$data,$options);
}
}
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 10:50:27
* @Description: 插入成功后的回调方法
*/
protected function _after_insert($data,$options) {
$this->after_write("insert",$data,$options);
} /**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 11:56:12
* @Description: 删除成功后的回调方法
*/
protected function _after_delete($data,$options) {
$this->after_write("delete",$data,$options);
}
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 11:03:18
* @Description: 更新或插入成功后和删除前写入系统日志
*/
function after_write($type,$data,$options)
{
$db_name = C('DB_PREFIX')."system_log"; //日志表
//如果是系统日志表则不处理,防止循环调用此方法
if(!$this->_is_array($data) || !$this->_is_array($options) || strcasecmp($options['table'],$db_name)==0) return ;
$model = M("SystemLog"); //日志表
$new_value = json_encode($data); // 去除前缀的表名
$_data['log_table'] = str_replace(C('DB_PREFIX'), "",$options['table']);
//更改时如果原数据未更改则不进行记录,防止重复记录
if("update" === $type){
//表主健
$_data['t_id'] = $data['id']; // 主健名称不是id
// 获取主健对应的数据
if($_data['id']){
$tablename = $options['table'];
$_data['t_id'] = $data[M($tablename)->getPk()];
}
// 如果最后一条的值没有更改则不记录
if($model->where($_data)->order("id desc")->getField("new_value")===$new_value) return;
}
$_data['log_type'] = $type;
$_data['new_value'] = $new_value;
$_data['log_user'] = $_SESSION['ADMIN_ID'];
$_data['create_time'] = date('Y-m-d H:i:s');
$_data['ip_address'] = get_client_ip(0,true);
$_data['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
try {
$model->add($_data);
} catch (Exception $e) {
\Think\Log::write('写入系统日志时发生错误,错误信息:'.$e->getMessage(),'WARN');
}
}
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 11:04:40
* @Description: 是否是数组
*/
function _is_array($array)
{
return ($array && is_array($array) && count($array)>0);
}
}
<?php /**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 12:03:57
* @Description: 基础价格Model
*/
namespace Common\Model;
use Common\Model\CommonModel;
class PriceModel extends CommonModel
{
/**
* @Author: HTL
* @Email: Huangyuan413026@163.com
* @DateTime: 2016-04-08 15:01:46
* @Description: 自动验证,合并父类验证规则
*/
function _initialize() { //自定义验证规则
$_val = array(
array('cost','/^[-0-9]{1,}$/','{%ERROR_ONLY_INTEGER}'),
array('price','/^[-0-9]{1,}$/','{%ERROR_ONLY_INTEGER}'),
); //合并父类的规则
//验证父类code、name字段
//当前模型的create_time字段自动填充
$this->_validate = array_merge (parent::get_validate(),$_val); // 移出父类的Code唯一性验证
//foreach ($this->_validate as $key => $value) {
// if($value[0]=='code' && $value[4]=='unique'){
// unset($this->_validate[$key]);
// }
//} //覆盖父类验证规则
$this->_validate = $_val;
}
}
CREATE TABLE `tp_system_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`log_type` VARCHAR(50) NOT NULL COMMENT '操作类别',
`log_table` VARCHAR(100) NOT NULL COMMENT '操作的表',
`log_user` VARCHAR(100) NOT NULL COMMENT '操作的用户',
`t_id` VARCHAR(50) NOT NULL COMMENT '操作的表的主健ID',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作的时间',
`new_value` TEXT NOT NULL COMMENT '操作后的新值',
`ip_address` VARCHAR(20) NOT NULL COMMENT 'Ip地址',
`user_agent` VARCHAR(500) NULL DEFAULT NULL COMMENT 'User-Agent:',
PRIMARY KEY (`id`),
INDEX `id` (`id`)
)
ThinikPhp 将数据库模型的增、删、改操作写入日志的更多相关文章
- C# ADO.NET (sql语句连接方式)(增,删,改)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- 好用的SQL TVP~~独家赠送[增-删-改-查]的例子
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...
- iOS sqlite3 的基本使用(增 删 改 查)
iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...
- ADO.NET 增 删 改 查
ADO.NET:(数据访问技术)就是将C#和MSSQL连接起来的一个纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中 也可以将数据库中的数据提取到内存中供程序调用 ADO.NET所有数据访 ...
- MVC EF 增 删 改 查
using System;using System.Collections.Generic;using System.Linq;using System.Web;//using System.Data ...
- 第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据
第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据 ADO.NET 为什么要学习? 我们要搭建一个平台(Web/Winform ...
- django ajax增 删 改 查
具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...
- StringBuilder修改字符串内容,增,删,改,插
package seday01;/** * 字符串不变对象特性只针对字符串重用,并没有考虑修改操作的性能.因此String不适合频繁修改内容. * 若有频繁修改操作,使用StringBuilder来完 ...
- iOS FMDB的使用(增,删,改,查,sqlite存取图片)
iOS FMDB的使用(增,删,改,查,sqlite存取图片) 在上一篇博客我对sqlite的基本使用进行了详细介绍... 但是在实际开发中原生使用的频率是很少的... 这篇博客我将会较全面的介绍FM ...
随机推荐
- CentOS配置通过DHCP的方式动态获取IP
修改/etc/sysconfig/network NETWORKING=yes 修改/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 ONBO ...
- PHP 获取时间
1.获取系统当前时间 echo "date('Y-m-d',time())"; 2.获取系统前一天时间 echo "date("Y-m-d",strt ...
- python易错题之lambda 以及 for循环中内嵌函数
li = [] for x in range(10): print(x) //在函数没有执行前(li[0]()),for 循环中x已经执行完,x会一直为 9 def fun(): print(x) / ...
- hdu3308
区间合并比较模板的题,就是求一个区间的LCIS 线段树维护左最大LCIS,右最大LCIS,区间LCIS 看代码就行 #include<iostream> #include<cstri ...
- js 事件对象
/* 事件绑定的格式: 元素节点.on + 事件类型 = function(){ } 元素节点 事件类型 on+事件类型:事件处理函数 [注]上述三者一绑定:生成一个新的事件对象. [注]触发事件以后 ...
- python 全栈开发,Day61(库的操作,表的操作,数据类型,数据类型(2),完整性约束)
昨日内容回顾 一.回顾 定义:mysql就是一个基于socket编写的C / S架构的软件 包含: ---服务端软件 - socket服务端 - 本地文件操作 - 解析指令(mysql语句) ---客 ...
- DDD领域模型查询方法实现(八)
在DDD.Domain工程文件夹Repository下创建RequestPage类: public class RequestPage { public RequestPage(int pagesiz ...
- ERP出库审核业务(四十四)
结束表单流程的代码: protected void btnSubmit_Click(object sender, EventArgs e) { if(this.txtreceiveDate.Text! ...
- 【C++ Primer 第11章】4. 无序容器
一.介绍 1. Hashtable和bucket 由于unordered_map内部采用的hashtable的数据结构存储,所以,每个特定的key会通过一些特定的哈希运算映射到一个特定的位置,我们知道 ...
- [转] 基于NodeJS的前后端分离的思考与实践(五)多终端适配
前言 近年来各站点基于 Web 的多终端适配进行得如火如荼,行业间也发展出依赖各种技术的解决方案.有如基于浏览器原生 CSS3 Media Query 的响应式设计.基于云端智能重排的「云适配」方案等 ...