基于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原创论坛
Oct 09 PHP
用PHP编程开发“虚拟域名”系统
Oct 09 PHP
php线性表顺序存储实现代码(增删查改)
Feb 16 PHP
php导出csv数据在浏览器中输出提供下载或保存到文件的示例
Apr 24 PHP
php smarty模板引擎的6个小技巧
Apr 24 PHP
phpMyAdmin自动登录和取消自动登录的配置方法
May 12 PHP
浅谈PHP中JSON数据操作
Jul 01 PHP
变量在 PHP7 内部的实现(二)
Dec 21 PHP
ThinkPHP中where()使用方法详解
Apr 19 PHP
微信自定义菜单的创建/查询/取消php示例代码
Aug 05 PHP
Zend Framework路由器用法实例详解
Dec 11 PHP
如何通过View::first使用Laravel Blade的动态模板详解
Sep 21 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新手上路(十二)
2006/10/09 PHP
pdo中使用参数化查询sql
2011/08/11 PHP
解析php类的注册与自动加载
2013/07/05 PHP
Yii框架实现邮箱激活的方法【数字签名】
2016/10/18 PHP
THINKPHP3.2使用soap连接webservice的解决方法
2017/12/13 PHP
WebGame《逆转裁判》完整版 代码下载(1月24日更新)
2007/01/29 Javascript
javascript 装载iframe子页面,自适应高度
2009/03/20 Javascript
jQuery ajax 路由和过滤器使用说明
2011/08/02 Javascript
Jquery动态替换div内容及动态展示的方法
2015/01/23 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
2016/01/18 Javascript
jQuery获取attr()与prop()属性值的方法及区别介绍
2016/07/06 Javascript
微信小程序中input标签详解及简单实例
2017/05/18 Javascript
Easyui在treegrid添加控件的实现方法
2017/06/23 Javascript
vue-router 权限控制的示例代码
2017/09/21 Javascript
关于js的三种使用方式(行内js、内部js、外部js)的程序代码
2018/05/05 Javascript
angularJs复选框checkbox选中进行ng-show显示隐藏的方法
2018/10/08 Javascript
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
鸿蒙系统中的 JS 开发框架
2020/09/18 Javascript
寻找网站后台地址的python脚本
2014/09/01 Python
Python通过属性手段实现只允许调用一次的示例讲解
2018/04/21 Python
Python3.6简单反射操作示例
2018/06/14 Python
计算Python Numpy向量之间的欧氏距离实例
2020/05/22 Python
Python实现壁纸下载与轮换
2020/10/19 Python
机关门卫岗位职责
2013/12/30 职场文书
家长评语大全
2014/01/22 职场文书
铲车司机岗位职责
2014/03/15 职场文书
干部鉴定材料
2014/05/18 职场文书
公司仓管员岗位职责
2015/04/01 职场文书
新年晚会开场白
2015/05/29 职场文书
校长新学期致辞
2015/07/30 职场文书
幼儿园班级管理心得体会
2016/01/07 职场文书
小学教师教学反思
2016/02/24 职场文书
《围炉夜话》110句人生箴言,精辟有内涵,引人深思
2019/10/23 职场文书
使用pandas模块实现数据的标准化操作
2021/05/14 Python
Python爬虫之自动爬取某车之家各车销售数据
2021/06/02 Python