基于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下一个阿拉伯数字转中文数字的函数
Jul 16 PHP
php 生成WML页面方法详解
Aug 09 PHP
在VS2008中编译MYSQL5.1.48的方法
Jul 03 PHP
PHP获取url的函数代码
Aug 02 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
Jan 11 PHP
将word转化为swf 如同百度文库般阅读实现思路及代码
Aug 09 PHP
使用php验证复选框有效性的示例
Nov 13 PHP
laravel5创建service provider和facade的方法详解
Jul 26 PHP
php删除一个路径下的所有文件夹和文件的方法
Feb 07 PHP
php7下的filesize函数
Sep 30 PHP
详解no input file specified 三种解决方法
Nov 29 PHP
PHP7变量处理机制修改
Mar 09 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之APC缓存详细介绍 apc模块安装
2014/01/13 PHP
推荐5款跨平台的PHP编辑器
2014/12/25 PHP
PHP实现随机发扑克牌
2020/04/22 PHP
从javascript语言本身谈项目实战
2006/12/27 Javascript
javascript 进度条 实现代码
2009/07/30 Javascript
实现png图片和png背景透明(支持多浏览器)的方法
2009/09/08 Javascript
JS图片切换的具体方法(带缩略图版)
2013/11/12 Javascript
js 日期比较相关天数代码
2014/04/02 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
jQuery插件HighCharts实现的2D堆条状图效果示例【附demo源码下载】
2017/03/14 Javascript
javascript使用btoa和atob来进行Base64转码和解码
2017/03/20 Javascript
js移动端图片压缩上传功能
2020/08/18 Javascript
详解Vue一个案例引发「内容分发slot」的最全总结
2018/12/02 Javascript
JS+HTML5 canvas绘制验证码示例
2018/12/05 Javascript
vue 使用 canvas 实现手写电子签名
2020/03/06 Javascript
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
Python中创建字典的几种方法总结(推荐)
2017/04/27 Python
Python Django2.0集成Celery4.1教程
2019/11/19 Python
Python中的Cookie模块如何使用
2020/06/04 Python
python 动态绘制爱心的示例
2020/09/27 Python
python复合条件下的字典排序
2020/12/18 Python
CSS3教程(9):设置RGB颜色
2009/04/02 HTML / CSS
详解HTML5中ol标签的用法
2015/09/08 HTML / CSS
美国独家设计师眼镜在线光学商店:Glasses Gallery
2017/12/28 全球购物
应届生会计电算化求职信
2013/10/03 职场文书
租房协议书
2014/04/10 职场文书
会计求职信范文
2014/05/24 职场文书
节约每一滴水演讲稿
2014/09/09 职场文书
创先争优宣传标语
2014/10/08 职场文书
公司地址变更通知
2015/04/25 职场文书
检讨书模板大全
2015/05/07 职场文书
纪录片信仰观后感
2015/06/08 职场文书
生产设备维护保养制度
2015/08/06 职场文书
2019 入党申请书范文
2019/07/10 职场文书
竞选稿之小学班干部
2019/10/31 职场文书
CSS实现多个元素在盒子内两端对齐效果
2021/03/30 HTML / CSS