如何使用php和mysql记录用户操作?

11

我正在开发我的CMS,希望记录用户和其他管理员的活动。例如:当新用户注册或管理员发布新闻时 -> 更新最后活动时间。

我想知道最好且最简单的方法是什么。


1
你是想在数据库中仅在发生操作时更新 last_activity 字段,还是要记录这个操作是什么? - Gordon
5个回答

23
  • 在你的数据库中创建一张表来记录用户活动。
  • 定义App中可能发生的各种活动类型。
  • 创建一个通用函数来将任何活动记录到那个表中。
  • 在你的应用程序中执行可记录日志的操作时,从任何位置调用该函数。

然后,您可以编写一个报告工具,使管理员可以访问这些已记录的活动,您可以按照用户、时间和活动类型进行过滤。

在我的日志框架中,我特别标记那些可能被视为恶意操作的活动,并分配不同的数字威胁值。如果某个用户的威胁值总和达到一定阈值,我将注销该用户。

理想情况下,如果您编写一个应用程序,您应该从一开始就编写像日志记录这样的基础设施代码,然后在以后的所有业务逻辑代码中使用它。

清理编辑:

随着时间的推移,你可能会在这张表中收集许多记录。根据您的要求,您可以采取不同的措施。

  • 删除x天(也许一年)之前的任何条目。

  • 删除某些类型的x天之前的任何条目,但保留其他类型的条目更长时间,或永久保存。

  • 将超过一定阈值的旧条目移动到存档日志表中。这样可以使您的主表保持较小,但也允许您在确实需要时访问旧的日志数据。我在我的审核日志页面上有一个复选框“使用归档”。


这样做会不会随着时间的推移导致过度拥挤?假设您托管了300,000个成员的网站并记录了他们的所有操作,您将如何处理如此庞大的信息量? - kemicofa ghost

4

基本答案

不要从头开始自己做,可以查看一些现有系统的实现方式,如果许可证允许,可以使用他们的设计和代码(确保您记录了使用的代码并在CMS的某个地方添加版权声明)。

可能有帮助的例子

我不确定哪些PHP CMS可以实现这一点,但我知道Django的管理应用程序可以。 Django是用Python实现的,但将此代码移植到PHP应该相当简单。即使代码不是直接移植的,也可以移植设计。

包含日志记录的文件位于models.py中的admin模块中。

一些关键方面:

日志记录表的数据模型:

class LogEntry(models.Model):
  action_time = models.DateTimeField(_('action time'), auto_now=True)
  user = models.ForeignKey(User)
  content_type = models.ForeignKey(ContentType, blank=True, null=True)
  object_id = models.TextField(_('object id'), blank=True, null=True)
  object_repr = models.CharField(_('object repr'), max_length=200)
  action_flag = models.PositiveSmallIntegerField(_('action flag'))
  change_message = models.TextField(_('change message'), blank=True)
  objects = LogEntryManager()

LogEntryManager保存实际的日志条目:

class LogEntryManager(models.Manager):
  def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''):
    e = self.model(None, None, user_id, content_type_id, smart_unicode(object_id), object_repr[:200], action_flag, change_message)
    e.save()

这样会不会随着时间过度填充?假设您拥有一个托管300,000个成员的网站并记录他们的所有操作?如何处理如此庞大的信息? - kemicofa ghost

2
我在活动中使用两个表格,一个为每个活动分配一个id,另一个仅记录用户id、活动id和时间戳。我这样做是因为int比string占用更少的空间,所以为什么要一遍又一遍地记录相同的字符串呢?第二个表不是真正必要的,你可以很容易地将操作代码保存在文本文件中供自己参考,但是数据库似乎更容易记住。
过去,我使用了一个函数来处理实际的日志记录操作,但下一次我将使用观察者模式。它似乎更加灵活,而且我已经不得不从旧代码中删除日志记录函数调用,因为它们并不需要记录任何东西。我更喜欢重用不需要编辑的代码。

0

使用PHP/JAVA FUNCTIONJQUERYAJAX数据发布方法非常简单......在发布解决方案之前,请先阅读以下两行内容:

为什么以及我们想要记录什么? ---正如我们所知,只有在数据库中记录交易--而不是所有的点击和检查--但是使用此解决方案是可能的....

以下是逐步解决方案:

1. create a DB Table -- to record these things
     a) Page Name.
     b) logged in user name
     c) session details (To record all the sessions).
     d) POST/GET data details (To record all the post/get data for the       
        page)
     e) Record Created Date.

或者任何你想要记录的东西。 2. 创建一个Jquery函数或PHP函数--它将自动触发每个页面。 3. 此函数将收集该页面的所有会话、用户登录详细信息以及传递到该页面的所有数据。 除此之外,您还可以记录从哪个页面调用这个新页面--这是一种非常简单且最佳的方式来实现日志记录功能,即使在已经运行的旧软件中也是如此:)

如果您想要使用我上面提到的所有代码--请在网络上搜索我定义的机制,只需需要函数代码--自动执行函数代码--简单


0

PHP和MYSQL

  1. 创建一个表来保存日志
CREATE TABLE `test_loq` (
   id int(11) PRIMARY KEY AUTO_INCREMENT,
   page varchar(255) NOT NULL,
   username varchar(255) NOT NULL,
   log_time datetime DEFAULT CURRENT_TIMESTAMP,
   log_action longtext NOT NULL,
   log_name varchar(255) NOT NULL,
   user_id int(11) NOT NULL,
   ip int(11) NOT NULL
   )

解释:

  • log_action是在此处执行的操作类型,您可以编写有关已执行操作的大量信息。
  • page是执行该操作的页面,即php文件的名称
  • log_name是所执行操作的名称
  • username是执行此操作的用户的名称
  • user_id是执行此操作的用户的ID
  • ip是用户的IP地址

2. 创建一个类
class log
{  
    CONST ENVIRONMENT = 'developemnt';

    private $id;
    protected $log_action;
    protected $username;
    protected $page;
    protected $ip;
    protected $log_name;
    private $user_id;

    public function __construct(string $log_action, string $username, string $log_name)
    {
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        
        if(!empty($_SESSION['id'])){
            $id = $_SESSION['id'];
        } else {
            $id = 0;
        }
        $this->log_action = $log_action;
        $this->username = $username;
        $this->log_name = $log_name;
        $this->user_id = $id;
        $this->page =  basename($_SERVER['PHP_SELF']);
        $this->ip = $ip;
    }

    public function createAction()
    {
        global $conn;

        if(!$conn) {
           echo mysqli_error($conn); die;
        }
        $sql = "INSERT INTO test_log (`log_action`,`username`,`log_name`,`page`,`user_id`,`ip`) values ('".$this->log_action."','".$this->username."','".$this->log_name."','".$this->page."','".$this->user_id."','".$this->ip."')" ;
        $sql_query = mysqli_query($conn,$sql);
        if(!$sql_query){
            echo mysqli_error($conn); die;
        }

        if(ENVIRONMENT == 'development'){
            $_SESSION['msg'] = 'A new log was created ' . $this->log_name;
        }
        
    } }

explain:
  • 环境可以是开发或生产环境,如果是开发环境,它将显示有关已生成日志的闪存消息
    3.记录一个操作!
    例如:记录登录尝试的操作 创建一个名为logincheck.php的php文件
    <?php 
    session_start();
    include("include/configurationadmin.php");
    //include_once('../include/classes/config.inc.php');
    
    $username = $_REQUEST['username'];
    $password = $_REQUEST['password'];
    $sql  = mysqli_query($conn,"select * from ".$sufix."admin where username='".$username."'") ;
    

// HERE HOW TO LOG ACTION

    $log = new log("Logging in attempt from $username" , $username ,'Login Attempt' );
    $log->createAction();
    
//SIMPLE AND COOL RIGHT?

    if(mysqli_num_rows($sql) > 0)
    {
        $rows = mysqli_fetch_assoc($sql);
        if(md5($password) == $rows['password']) {
            $_SESSION['id'] = $rows['id'];
            $_SESSION['username'] = $rows['username'];
            $_SESSION['usertype'] = $rows['type'];
            mysqli_query($conn,"update ".$sufix."admin set lastlogin='".date('Y-m-d')."' where id = '".$rows['id']."' and username='".$rows['username']."'") ;
            $domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
            setcookie('rrdssrdda', $rows['id'], time()+120, '/', $domain, false);
            header("Location: http://localhost/test/admin-new/dashboard");
            exit();
        } else {
            $_SESSION['message']="<div class='alert alert-danger' role='alert'>Invalid userid/password!</div>";
            header("Location: http://localhost/test/admin-new/");
            exit();
    
        }
    
    } else { 
        $_SESSION['message']="<div class='alert alert-danger' role='alert'>Invalid userid/password!</div>";
        header("Location: http://localhost/test/admin-new/");
        exit();
       
   } ?>

编程快乐!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接