You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为PHP+MySQL项目实现文件存储的客户端操作日志记录

实现思路
  • 统一日志格式:每条日志固定包含操作时间、操作类型、操作人唯一标识(用户ID/用户名)、客户端IP、操作描述核心字段,降低后续日志解析成本
  • 封装独立日志工具:把日志写入逻辑单独抽成公共类,和业务逻辑解耦,后续要调整存储规则(比如从文件改存数据库)不需要动业务代码
  • 业务点埋点:
    1. 在登录逻辑验证账号密码通过后,调用日志方法写入登录操作
    2. 在数据库新增逻辑执行成功后,调用日志方法写入新增操作
  • 安全注意:操作人身份必须从服务端Session/校验通过的Token中获取,禁止使用前端传递的用户信息,避免日志被伪造
代码实现示例

公共日志类

class OperationLogger
{
    // 日志存储路径请放到项目非web可访问目录,避免被外界直接下载
    private $logFilePath = __DIR__ . '/../logs/operation/operation.log';

    public function __construct()
    {
        // 自动创建日志目录
        $logDir = dirname($this->logFilePath);
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
    }

    /**
     * 写入操作日志
     * @param string $operateType 操作类型 login/add/edit/delete
     * @param string $operator 操作人信息 格式示例:1001:张三
     * @param string $operateDesc 操作描述
     * @return void
     */
    public function writeLog(string $operateType, string $operator, string $operateDesc = '')
    {
        $logItem = [
            date('Y-m-d H:i:s'),
            $operateType,
            $operator,
            $_SERVER['REMOTE_ADDR'] ?? 'unknown_ip',
            trim($operateDesc)
        ];
        // 用特殊符号分隔字段,方便后续脚本批量解析
        $logLine = implode(' | ', $logItem) . PHP_EOL;
        // 加独占锁避免并发写入时内容错乱
        file_put_contents($this->logFilePath, $logLine, FILE_APPEND | LOCK_EX);
    }
}

登录场景调用示例

session_start();
// 账号密码验证通过后的逻辑
$userInfo = $db->query("SELECT id,username FROM users WHERE account = ? AND password = ?", [$account, $md5Pwd])->fetch();
if ($userInfo) {
    $_SESSION['user_id'] = $userInfo['id'];
    $_SESSION['username'] = $userInfo['username'];
    // 写入登录日志
    $logger = new OperationLogger();
    $logger->writeLog('login', "{$userInfo['id']}:{$userInfo['username']}", "用户登录系统");
}

新增数据场景调用示例

session_start();
// 先校验登录状态
if (empty($_SESSION['user_id'])) {
    die('请先登录后操作');
}
// 处理新增数据逻辑
$newInsertId = $db->execute("INSERT INTO table (col1,col2) VALUES (?,?)", [$val1, $val2]);
if ($newInsertId) {
    // 写入新增操作日志
    $operator = "{$_SESSION['user_id']}:{$_SESSION['username']}";
    $logger = new OperationLogger();
    $logger->writeLog('add', $operator, "新增数据ID:{$newInsertId}");
}
优化建议
  • 并发量较高的项目可以先把日志写入内存队列,异步落地到文件,避免阻塞业务请求
  • 按天拆分日志文件,避免单个日志文件过大导致查询、清理困难
  • 敏感操作日志可以额外加签名校验,防止日志被恶意篡改

内容的提问来源于stack exchange,提问作者IDKHowToScript

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:36:05