基于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 相关文章推荐
php 获取客户端的真实ip
Nov 30 PHP
QQ登录 PHP OAuth示例代码
Jul 20 PHP
PHP输出时间差函数代码
Jan 28 PHP
自己写了一个php检测文件编码的函数
Apr 21 PHP
Smarty foreach控制循环次数的一些方法
Jul 01 PHP
curl 出现错误的调试方法(必看)
Feb 13 PHP
基于php(Thinkphp)+jquery 实现ajax多选反选不选删除数据功能
Feb 24 PHP
PHP下载远程图片的几种方法总结
Apr 07 PHP
PHP实现类似题库抽题效果
Aug 16 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
Nov 19 PHP
Yii 框架使用Forms操作详解
May 18 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中call_user_func函数使用注意事项
2014/11/21 PHP
Laravel使用模型实现like模糊查询的例子
2019/10/24 PHP
php如何获取Http请求
2020/04/30 PHP
php+js实现的拖动滑块验证码验证表单操作示例【附源码下载】
2020/05/27 PHP
javascript 写类方式之三
2009/07/05 Javascript
javascript基础知识大集锦(二) 推荐收藏
2011/01/13 Javascript
解决jquery异步按一定的时间间隔刷新问题
2012/12/10 Javascript
JavaScript实现三阶幻方算法谜题解答
2014/12/29 Javascript
jQuery+slidereveal实现的面板滑动侧边展出效果
2015/03/14 Javascript
理解Javascript的动态语言特性
2015/06/17 Javascript
jQuery中hover与mouseover和mouseout的区别分析
2015/12/24 Javascript
Nodejs学习item【入门手上】
2016/05/05 NodeJs
Vue组件tree实现树形菜单
2017/04/13 Javascript
微信小程序实现拖拽 image 触摸事件监听的实例
2017/08/17 Javascript
JavaScript学习笔记之惰性函数示例详解
2017/08/27 Javascript
微信小程序实现轮播图效果
2017/09/07 Javascript
浅谈React碰到v-if
2018/11/04 Javascript
vue导入.md文件的步骤(markdown转HTML)
2020/12/31 Vue.js
[03:55]显微镜下的DOTA2特别篇——430灰烬之灵神级操作
2014/06/24 DOTA
python如何使用unittest测试接口
2018/04/04 Python
Python封装原理与实现方法详解
2018/08/28 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
python flask 如何修改默认端口号的方法步骤
2019/07/12 Python
Pyinstaller 打包exe教程及问题解决
2019/08/16 Python
Whittard官方海外旗舰店:英国百年茶叶品牌
2018/02/22 全球购物
环保建议书600字
2014/05/14 职场文书
化工专业自荐书
2014/06/16 职场文书
理财学专业自荐书
2014/06/28 职场文书
新闻传播专业求职信
2014/07/22 职场文书
2014年度安全生产目标管理责任书
2014/07/25 职场文书
优秀党员先进材料
2014/12/18 职场文书
给老婆的保证书
2015/01/16 职场文书
结婚老公保证书
2015/02/26 职场文书
大学生求职自荐信范文
2015/03/04 职场文书
2015年公务员试用期工作总结
2015/05/28 职场文书
python基础之文件处理知识总结
2021/05/23 Python