基于PHP实现用户在线状态检测


Posted in PHP onNovember 10, 2020

这个是基于ThinkPHP框架的,其他的可以自己根据需求改

1.先新建一个tags.php文件,放在配置目录Conf下。

<?php
 /*
 * 添加行为
 *
 */
 return array(
  'action_begin' => array('OnlineCheck'),
 );
 ?>

2.定义具体的功能

<?php
 /*
 * 定义行为: 在线更新
 */
 class OnlineCheckBehavior extends Behavior {
  //行为参数
  protected $options = array(
    'ONLINE_CHECK' => true, // 默认进行在线
    'ONLINE_CHECK_TIME' => 10, // 默认5分钟未活动,说明已下线
  );
  public function run(&$params) {
    if (C('ONLINE_CHECK')) {
      // 更新session
      if ((session('?login_account')) && (time() - session('access_time') > 60)) {
        session('access_time', time());
      }
      // 在线更新
      $ip = ip2long(get_client_ip());
      $online = M('Online');
      // 先删除在线表中 超过5分钟未活动的记录
      //$sql = ' delete from __TABLE__ where ';
      $map['lasttime'] = array('lt', time() - C('ONLINE_CHECK_TIME') * 60);
      $icount = $online->where($map)->delete();
      if (session('?login_account')) { // 如果是登录用户
        $map = array();
        $map['uid'] = session('login_uid');
        $map['lastip'] = $ip;
        $id = $online->where($map)->getField('id');
        if (empty($id)) { // 不存在在线记录,则清空session
          session(null);
        } else {
          $map = array();
          $map['id'] = array('eq', $id);
          $data['lasttime'] = time();
          $data['lastip'] = $ip;
          $online->where($map)->save($data);
        }
      } else { // 不是登录用户 游客
        unset($map);
        $map['lastip'] = array('eq', $ip);
        $id = $online->where($map)->getField('id');
        //dump($id);
        if (empty($id)) { // 不存在在线记录, 则添加
          $data = array();
          $data['uid'] = 0;
          $data['account'] = 'Guest';
          $data['nickname'] = '游客';
          $data['lasttime'] = time();
          $data['lastip'] = $ip;
          $online->add($data);
        } else {
          $map = array();
          $map['id'] = array('eq', $id);
          $data['lasttime'] = time();
          $data['lastip'] = $ip;
          $online->where($map)->save($data);
        }
      }
    }
  }
 }
 ?>

3.在具体的登录方法上添加

// 登录检测
  public function checkLogin() {
    // $this->redirect($url);
    $username = strtolower($this->_param('usr'));
    $pwd = $this->_param('pwd');
    $url = $this->_param('url'); // 目标地址
    $is_error = false;
    if (empty($username) or empty($pwd)) {
      $this->assign('error_msg', '用户名和口令不能为空');
      $is_error = true;
    }
    if (!$is_error) {
      $model = M('Usr');
      $map['account'] = $username;
      $map['upwd'] = strtoupper(md5($pwd));
      $icount = $model->where($map)->count();
      if ($icount == 1) {
        $list = $model->where($map)->find();
        // 检测用户是否在线
        if ($this->isOnline($list['id'])) {
          // <editor-fold defaultstate="collapsed" desc="if开始">
          if ($list['status']) {
            session('login_account', $username);
            session('login_nickname', $list['nickname']);
            session('last_time', toDate($list['last_time']));
            if ($list['last_ip']) {
              session('last_ip', long2ip($list['last_ip']));
            } else {
              session('last_ip', get_client_ip());
            }
            session('login_count', $list['login_count']);
            session('login_uid', $list['id']);
            session('login_pwd', $list['upwd']);
            session('access_time', time()); //用户最后点击页面时间 session超时使用
            ///
            $map['id'] = $list['id'];
            $data['last_time'] = time();
            $data['last_ip'] = ip2long(get_client_ip());
            $model->where($map)->save($data);
            $model->where($map)->setInc('login_count', 1);
            // 检测是否有同一IP的记录,有更新,否则 添加
            $online = M('Online');
            $map = array();
            $map['lastip'] = ip2long(get_client_ip());
            $online_id = $online->where($map)->getField('id');
            if (empty($online_id)) {
              // 插入在线用户表
              $data = array();
              $data['uid'] = $list['id'];
              $data['account'] = $list['account'];
              $data['nickname'] = $list['nickname'];
              $data['lasttime'] = time();
              $data['lastip'] = ip2long(get_client_ip());
              $online->add($data);
            }else{
               // 更新在线用户表
              $data = array();
              $data['uid'] = $list['id'];
              $data['account'] = $list['account'];
              $data['nickname'] = $list['nickname'];
              $data['lasttime'] = time();
              //$data['lastip'] = ip2long(get_client_ip());
              $online->where($map)->save($data);
            }
          } else {
            $is_error = true;
            $this->assign('error_msg', '此用户已被禁止登录!');
          }
          // </editor-fold>  if 结束
        } else {
          $is_error = true;
          $this->assign('error_msg', '此用户名已在其他电脑登陆,请' . C('ONLINE_CHECK_TIME') .'分钟后再试!');
        }
      } else {
        $is_error = true;
        $this->assign('error_msg', '错误的用户名或口令!');
      }
    }
    if ($is_error) {
      $this->display('login');
    } else {
      $this->redirect('Index/index');
 //      if (empty($url)) {
 //        $this->redirect('Index/index');
 //      } else {
 //        $this->redirect($url);
 //      }
    }
  }
 /**
   * 检测用户是否在线
   * @access private
   * @param int $uid 用户ID
   * @return Boolean true=不在线
   */
  private function isOnline($uid) {
    $ip = ip2long(get_client_ip());
    $online = M('Online');
    $map['uid'] = array('eq', $uid);
    $list = $online->where($map)->find();
    if (empty($list)) { // 不存在
      return true;
    } else { // 存在,检测IP是否一致,否则,检测是否超过5分钟
      if ($list['lastip'] == $ip) {
        return true;
      } else {
        if ($list['lasttime'] < time() - C('ONLINE_CHECK_TIME') * 60) {
          return true;
        } else {
          return false;
        }
      }
    }
  }

以上就是具体的PHP在线状态检测,同一时间只有一个用户可以存在,不过还没有考虑到非正常掉线等,cookie,session意外的处理,但是先分享出来吧

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
在任意字符集下正常显示网页的方法一
Apr 01 PHP
PHP 导出数据到淘宝助手CSV的方法分享
Feb 27 PHP
PHP Zip解压 文件在线解压缩的函数代码
May 26 PHP
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
Jan 03 PHP
LotusPhp笔记之:Cookie组件的使用详解
May 06 PHP
解析MySql与Java的时间类型
Jun 22 PHP
php解析json数据实例
Aug 19 PHP
PHP6新特性分析
Mar 03 PHP
php打乱数组二维数组多维数组的简单实例
Jun 17 PHP
php实现微信企业号支付个人的方法详解
Jul 26 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
Jul 21 PHP
PHP文件上传小程序 适合初学者学习!
May 23 PHP
PHP常量DIRECTORY_SEPARATOR原理及用法解析
Nov 10 #PHP
PHP safe_mode开启对于PHP系统函数有什么影响
Nov 10 #PHP
通过PHP实现用户注册后邮箱验证激活
Nov 10 #PHP
PHP中的异常处理机制深入讲解
Nov 10 #PHP
基于php解决json_encode中文UNICODE转码问题
Nov 10 #PHP
ThinkPHP5分页paginate代码实例解析
Nov 10 #PHP
关于PHP求解三数之和问题详析
Nov 09 #PHP
You might like
php学习笔记 php中面向对象三大特性之一[封装性]的应用
2011/06/13 PHP
php设计模式 Factory(工厂模式)
2011/06/26 PHP
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
PHP输出时间差函数代码
2013/01/28 PHP
php curl基本操作详解
2013/07/23 PHP
php cookie使用方法学习笔记分享
2013/11/07 PHP
用php来限制每个ip每天浏览页面数量的实现思路
2015/02/24 PHP
php+ajax实现文件切割上传功能示例
2020/03/03 PHP
Javascript学习笔记 delete运算符
2011/09/13 Javascript
JS判断文本框内容改变事件的简单实例
2014/03/07 Javascript
jQuery实现仿美橙互联两级导航菜单效果完整实例
2015/09/17 Javascript
jQuery实现伪分页的方法分享
2016/02/17 Javascript
Bootstrap3.0学习教程之JS折叠插件
2016/05/27 Javascript
完美解决jQuery fancybox ie 无法显示关闭按钮的问题
2016/11/29 Javascript
es7学习教程之Decorators(修饰器)详解
2017/07/21 Javascript
webpack实现热加载自动刷新的方法
2017/07/30 Javascript
angularJS1 url中携带参数的获取方法
2018/10/09 Javascript
在小程序中推送模板消息的实现方法
2019/07/22 Javascript
vue.js实现三级菜单效果
2019/10/19 Javascript
Python 冒泡,选择,插入排序使用实例
2015/02/05 Python
python获取从命令行输入数字的方法
2015/04/29 Python
在python中使用with打开多个文件的方法
2019/01/07 Python
Python实现井字棋小游戏
2020/03/09 Python
Python request post上传文件常见要点
2020/11/20 Python
10种CSS3实现的loading动画,挑一个走吧?
2020/11/16 HTML / CSS
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
HOTEL INFO英国:搜索全球酒店
2019/08/08 全球购物
精选干货:Java精选笔试题附答案
2014/01/18 面试题
技术总监的工作职责
2013/11/13 职场文书
幼儿园大班评语大全
2014/04/17 职场文书
小学校长先进事迹材料
2014/05/13 职场文书
2014年人事专员工作总结
2014/11/19 职场文书
委托证明范本
2014/11/25 职场文书
2016新教师岗前培训心得体会
2016/01/08 职场文书
python自动化操作之动态验证码、滑动验证码的降噪和识别
2021/08/30 Python
2022年四月新番
2022/03/15 日漫