摘要
近期在对后台系统的优化过程中,
了解到 ThinkPHP5
框架所提供的 钩子
行为记录的技巧使用
感觉在代码规范、AOP (面向切面编程)上都很有值得借鉴的地方
在此进行整理一番,希望帮到有需要的小伙伴
☞ 实例操作
以我的实际操作为例,演示步骤如下:
行为入口定义
行为类的定义很简单,一般来说只需要定义一个行为入口方法
run
即可
application/cm/behavior
目录中,新建了一个行为类 "CmsLogger"
namespace app\cms\behavior;
use app\common\lib\BaseException;
use app\common\lib\IAuth;
use app\common\model\XcmsOpLogs;
use think\facade\Request;
use think\facade\Response;
/**
* 行为日志
* Class CmsOp
* @package app\cms\behavior
*/
class CmsLogger
{
/**
* @param string $params
* @throws BaseException
*/
public function run($params = ''){
if (empty($params)){
throw new BaseException(['msg' => '日志信息不能为空']);
}
if (is_array($params)){
list('admin_id' => $admin_id, 'admin_name' => $admin_name, 'msg' => $message) = $params;
}else{
list($admin_id,$admin_name) = IAuth::getAdminIDCurrLogged();
$message = $params;
}
$LogData = [
'message' => $message,
'admin_id' => $admin_id,
'admin_name' => $admin_name,
'status_code' => Response::getCode(),
'method' => Request::method(),
'path' => '/' . Request::path(),
];
(new XcmsOpLogs())::create($LogData);
}
}
统一定义行为
我直接在应用目录下面定义
tags.php
文件来统一定义行为
相关数据记录设计
我习惯将行为日志记录到
mySQL
数据库中(可根据自己的需求选择记录方式)
CREATE TABLE `tp5_xcms_op_logs` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`admin_id` int(10) unsigned NOT NULL DEFAULT '0',
`admin_name` varchar(24) NOT NULL DEFAULT '',
`status_code` int(11) unsigned NOT NULL DEFAULT '0',
`method` varchar(20) NOT NULL DEFAULT '',
`path` varchar(50) NOT NULL DEFAULT '',
`message` varchar(300) NOT NULL DEFAULT '',
`create_time` datetime(3) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='CMS 行为日志记录表';
闭包传参,执行行为
官方提供了两种方式,一种为
闭包支持
,另一种为直接执行行为
☞ 后续总结
☛ 附录
经验这种东西,需要自己根据需求,参考后做最适合自己的优化,才是最有效率的!
▷ 参考文章
▷ 提供一种自定义公共方法记录行为日志的处理方式
在没有接触
Hook (钩子)
技巧使用前,在此提供一下我所使用的记录日志方式
common.php
中,定义如下方法/**
* 操作日志 添加记录
* @param int $opStatus 操作标记位 ,非零则进行日志的记录
* @param string $opTag 所记录业务日志确定的标签
* 当前定义 ———— "ARTICLE": 文章操作业务;"TODAY":今日赠言业务;"GOODS":商品操作业务
* @param int $op_id 所操作的目标记录ID
* @param string $op_msg 记录操作信息
* @return bool|int|string
*/
function insertCmsOpLogs($opStatus = 0,$opTag = '',
$op_id = 0,$op_msg = ''){
if (!$opStatus){
return false;
}else{
list($cmsAID) = IAuth::getAdminIDCurrLogged();
$opData = [
'op_id' => $op_id,
'tag' => $opTag,
'admin_id' => $cmsAID,
'add_time' => date('Y-m-d H:i:s',time()),
'op_msg' => $op_msg
];
if ($opTag){
$opStatus = Db::name('xcmsLogs')->insert($opData);
}else{
return false;
}
return $opStatus;
}
}
/**
* 获取操作日志
* @param int $op_id
* @param string $opTag 所记录业务日志确定的标签
* 当前定义 ———— "ARTICLE": 文章操作业务;"TODAY":今日赠言业务;"GOODS":商品操作业务
* @return array|PDOStatement|string|\think\Collection
*/
function getCmsOpViewLogs($op_id= 0,$opTag = ''){
$logs = Db::name('xcmsLogs l')
->field('l.*,a.user_name')
->join('xadmins a','a.id = l.admin_id')
->where([['tag','=',$opTag],['op_id','=',$op_id]])
->order('id','desc')
->select();
return isset($logs)?$logs:[];
}
CREATE TABLE `tp5_xcms_logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tag` varchar(10) NOT NULL COMMENT '标签,为了区分所记录不同业务的日志',
`op_id` int(11) NOT NULL DEFAULT '0' COMMENT '操作对象 ID',
`op_msg` varchar(12) NOT NULL COMMENT '操作备案',
`admin_id` int(11) NOT NULL DEFAULT '0' COMMENT '操作管理员ID',
`add_time` datetime NOT NULL COMMENT '记录添加时间',
PRIMARY KEY (`id`),
KEY `index_op_admin_id` (`op_id`,`admin_id`),
KEY `tag_index` (`tag`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='业务 行为记录日志表';
insertCmsOpLogs()
getCmsOpViewLogs()
★ 对比总结
1. 相对来说,实现最终的功能可以有多种方式,不必纠结
2. 多数自己设计的公共方法,对自己业务而言,更灵活
3. ThinkPHP5 提供的 Hook 技巧,具有的切面思想是最值得借鉴的;
同时,在新的行为设计出现后,方便进行扩展,相对框架来说更具有规范性;
最大的优势,在于受众面的宽阔,便于交流