前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ThinkPHP5.1 Hook(钩子)的理解及应用示例

ThinkPHP5.1 Hook(钩子)的理解及应用示例

作者头像
泥豆芽儿 MT
发布2022-01-05 13:56:56
9730
发布2022-01-05 13:56:56
举报
文章被收录于专栏:木头编程 - moTzxx

摘要

  • 近期在对后台系统的优化过程中, 了解到 ThinkPHP5 框架所提供的 钩子 行为记录的技巧使用 感觉在代码规范、AOP (面向切面编程)上都很有值得借鉴的地方 在此进行整理一番,希望帮到有需要的小伙伴
  • 官方文档 - 钩子和行为

☞ 实例操作

以我的实际操作为例,演示步骤如下:

第一步、 行为入口定义

行为类的定义很简单,一般来说只需要定义一个行为入口方法 run即可

  • 我在目录 application/cm/behavior 目录中,新建了一个行为类 "CmsLogger" 源码如下 (具体逻辑可根据自己的需求设定):
代码语言:javascript
复制
<?php

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 数据库中(可根据自己的需求选择记录方式)

  • 在此,我设计的一个行为日志表如下:
代码语言:javascript
复制
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 行为日志记录表';

第四步、闭包传参,执行行为

官方提供了两种方式,一种为 闭包支持,另一种为 直接执行行为

  • 在此,我选择的是第一种方式 最简单的代码参考如下:
  • [注]:对于其中的传参一般可以分为 string/array 类型,演示我的调用位置如下:

☞ 后续总结

  • 根据前面的步骤,代码逻辑编写完成后,最终会在行为日志表中得到如下记录:
  • 该记录,一般用于管理员后台监控 或者,为登录平台的用户显示其操作日志,方便问题追溯 后续,可根据自己系统的需求,对该行为日志进行提取即可 …

☛ 附录

经验这种东西,需要自己根据需求,参考后做最适合自己的优化,才是最有效率的!

▷ 参考文章

▷ 提供一种自定义公共方法记录行为日志的处理方式

在没有接触 Hook (钩子) 技巧使用前,在此提供一下我所使用的记录日志方式

1、 首先,在公共方法文件 common.php 中,定义如下方法
代码语言:javascript
复制
/**
 * 操作日志 添加记录
 * @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:[];
}
  • 对该方法中,操作的记录数据表,建表语句参考如下:
代码语言:javascript
复制
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='业务 行为记录日志表';
2、然后,确定在代码逻辑中,需要记录日志的位置,调用 insertCmsOpLogs()
3、在需要展示操作日志的时候,调用getCmsOpViewLogs()
  • 我对简单业务处理的操作日志展示如下:
★ 对比总结
代码语言:javascript
复制
1. 相对来说,实现最终的功能可以有多种方式,不必纠结
2. 多数自己设计的公共方法,对自己业务而言,更灵活
3. ThinkPHP5 提供的 Hook 技巧,具有的切面思想是最值得借鉴的;
	同时,在新的行为设计出现后,方便进行扩展,相对框架来说更具有规范性;
	最大的优势,在于受众面的宽阔,便于交流
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/07/27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • ☞ 实例操作
    • 第一步、 行为入口定义
      • 第二步、统一定义行为
        • 第三步、相关数据记录设计
          • 第四步、闭包传参,执行行为
          • ☞ 后续总结
          • ☛ 附录
            • ▷ 参考文章
              • ▷ 提供一种自定义公共方法记录行为日志的处理方式
                • 1、 首先,在公共方法文件 common.php 中,定义如下方法
                • 2、然后,确定在代码逻辑中,需要记录日志的位置,调用 insertCmsOpLogs()
                • 3、在需要展示操作日志的时候,调用getCmsOpViewLogs()
                • ★ 对比总结
            相关产品与服务
            ICP备案
            在中华人民共和国境内从事互联网信息服务的网站或APP主办者,应当依法履行备案手续。腾讯云为您提供高效便捷的 ICP 备案服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档