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 ...
随机推荐
- 【ES】学习2-搜索
1.空搜索 返回所有索引下的所有文档 GET /_search 设置超时.timeout 不是停止执行查询,它仅仅是告知正在协调的节点返回到目前为止收集的结果并且关闭连接.在后台,其他的分片可能仍在执 ...
- poj2114 树分治(点分治)
poj1741板子套一套,统计对数的方式改一下,可以在O(n)时间内统计对数 最后不要忘记输出最后的“.” /* 给定一棵边权树,是否存在一条路径使得其长度为恰好为x 把1741的板子改为求点对之间的 ...
- python 全栈开发,Day106(结算中心(详细),立即支付)
昨日内容回顾 1. 为什么要开发路飞学城? 提供在线教育的学成率: 特色: 学,看视频,单独录制增加趣味性. 练,练习题 改,改学生代码 管,管理 测,阶段考核 线下:8次留级考试 2. 组织架构 - ...
- HDU1850 尼姆博弈求可行方案数目
尼姆博弈(Nimm's Game) 题型 尼姆博弈模型,大致上是这样的: 有3堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取1个,多者不限,最后取光者得胜. 分析 1.首先自己想一下 ...
- 2018-2019 2 20165203 《网络对抗技术》 Exp2 后门原理与实践
2018-2019 2 20165203 <网络对抗技术> Exp2 后门原理与实践 实验内容 1.使用netcat获取主机操作Shell,cron启动 (0.5分) 2.使用socat获 ...
- C/S权限系统得到拼音和五笔的自定义函数(二)
得到五笔: CREATE FUNCTION [dbo].[fun_getWB](@Str VARCHAR(2000)) RETURNS VARCHAR(2000) AS BEGIN DECLARE @ ...
- poj 2349 求MST中第S大的权值
题目大意: 有一些炮台,如果这个炮台有卫星接收器,那么任意两个有卫星接收器的炮台可以通信,不受距离限制:否者,两个炮台之间只能通过对讲机通信,这是受距离限制的.要买一种对讲机,用在需要的炮台上,要求所 ...
- Python os.path.basename
一.获取对应路径下文件的名字 >>> os.path.basename("/etc/sysconfig/selinux") 'selinux' >>& ...
- Trident简介
1.引入 0.7版本:多条记录封装成批量,引入事务控制. 0.9版本:丢弃事务API,开始基于Storm之上的框架. 2.介绍 3.批次划分与事务实现 二:事务管理 4.事务处理机制 不透明事务:增加 ...
- 009 使用servlet API作为参数
1.哪些可以使用 MVC中的Handler方法可以接受ServletAPI类型的参数. 2.controller package com.spring.it; import java.io.IOExc ...