基于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 HTML代码串截取代码
Dec 29 PHP
php用数组返回无限分类的列表数据的代码
Aug 08 PHP
php截取字符串并保留完整xml标签的函数代码
Feb 06 PHP
Smarty模板学习笔记之Smarty简介
May 20 PHP
php 魔术方法详解
Nov 11 PHP
ThinkPHP模版中导入CSS和JS文件的方法
Nov 29 PHP
php实现utf-8转unicode函数分享
Jan 06 PHP
Laravel 5 框架入门(三)
Apr 09 PHP
yii2中结合gridview如何使用modal弹窗实例代码详解
Jun 12 PHP
thinkPHP模板算术运算相关函数用法分析
Jul 12 PHP
微信公众号开发客服接口实例代码
Oct 21 PHP
php数组指针操作详解
Feb 14 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自带的ZipArchive压缩文件并下载打包好的文件
2012/06/13 PHP
关于Blog顶部的滚动导航条代码
2006/09/25 Javascript
JavaScript 图像动画的小demo
2012/05/23 Javascript
jquery 之 $().hover(func1, funct2)使用方法
2012/06/14 Javascript
Jquery通过JSON字符串创建JSON对象
2014/08/24 Javascript
Javascript Memoizer浅析
2014/10/16 Javascript
JS与jQ读取xml文件的方法
2015/12/08 Javascript
微信小程序 swiper制作tab切换实现附源码
2017/01/21 Javascript
Vue.js实现简单动态数据处理
2017/02/13 Javascript
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
js中如何完美的解析数据
2018/03/18 Javascript
浅谈Vue数据响应思路之数组
2018/11/06 Javascript
浅谈es6中的元编程
2020/12/01 Javascript
浅谈JSON5解决了JSON的两大痛点
2020/12/14 Javascript
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
Python基于numpy灵活定义神经网络结构的方法
2017/08/19 Python
Python如何快速上手? 快速掌握一门新语言的方法
2017/11/14 Python
Python实现控制台中的进度条功能代码
2017/12/22 Python
python做量化投资系列之比特币初始配置
2018/01/23 Python
用python打印菱形的实操方法和代码
2019/06/25 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
2020/02/04 Python
OpenCV图片漫画效果的实现示例
2020/08/18 Python
CSS3盒子模型详解
2013/04/24 HTML / CSS
魔幻般冒泡背景的CSS3按钮动画
2016/02/27 HTML / CSS
AC Lens:购买隐形眼镜
2017/02/26 全球购物
有机童装:Toby Tiger
2018/05/23 全球购物
美国医疗用品、医疗设备和家庭保健用品商店:Medical Supply Depot
2018/07/08 全球购物
什么是java序列化,如何实现java序列化
2012/11/14 面试题
职业生涯规划怎么写
2013/12/29 职场文书
儿媳婚宴答谢词
2014/01/14 职场文书
总经理工作职责范文
2014/03/14 职场文书
文明之星事迹材料
2014/05/09 职场文书
多媒体编辑专业毕业生求职信
2014/06/13 职场文书
学期个人工作总结
2015/02/13 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
详细了解java监听器和过滤器
2021/07/09 Java/Android