基于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 Google的translate API代码
Dec 10 PHP
Fatal error: Call to undefined function curl_init()解决方法
Apr 09 PHP
PHP 中关于ord($str)&amp;gt;0x80的详细说明
Sep 23 PHP
PHP保留两位小数并且四舍五入及不四舍五入的方法
Sep 22 PHP
PHP中time(),date(),mktime()区别介绍
Sep 28 PHP
PHP程序漏洞产生的原因分析与防范方法说明
Mar 06 PHP
php清空(删除)指定目录下的文件,不删除目录文件夹的实现代码
Sep 04 PHP
PHP页面输出时js设置input框的选中值
Sep 30 PHP
php PDO实现的事务回滚示例
Mar 23 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
May 28 PHP
Yii2框架视图(View)操作及Layout的使用方法分析
May 27 PHP
PHP实现简单注册登录系统
Dec 28 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 全文搜索和替换的实现代码
2008/07/29 PHP
发一个php简单的伪原创程序,配合商城采集用的
2010/10/12 PHP
php 模拟get_headers函数的代码示例
2013/04/27 PHP
基于PHP+Ajax实现表单验证的详解
2013/06/25 PHP
PHP实现一维数组与二维数组去重功能示例
2018/05/24 PHP
JAVASCRIPT keycode总结
2009/02/04 Javascript
JQuery与Ajax常用代码实现对比
2009/10/03 Javascript
跨域请求之jQuery的ajax jsonp的使用解惑
2011/10/09 Javascript
js统计录入文本框中字符的个数并加以限制不超过多少
2014/05/23 Javascript
jQuery插件animateSlide制作多点滑动幻灯片
2015/06/11 Javascript
jquery实现select下拉框美化特效代码分享
2015/08/18 Javascript
js实现人民币大写金额形式转换
2016/04/27 Javascript
使用jQuery给input标签设置默认值
2016/06/20 Javascript
json对象与数组以及转换成js对象的简单实现方法
2016/06/24 Javascript
深入理解JavaScript中Ajax
2016/08/02 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
Vue 实现前端权限控制的示例代码
2019/07/09 Javascript
vue移动端城市三级联动组件使用详解
2019/07/26 Javascript
js实现弹窗效果
2020/08/09 Javascript
Python使用修饰器执行函数的参数检查功能示例
2017/09/26 Python
解决python中使用plot画图,图不显示的问题
2018/07/04 Python
对numpy中数组转置的求解以及向量内积计算方法
2018/10/31 Python
python 解压、复制、删除 文件的实例代码
2020/02/26 Python
Python requests模块cookie实例解析
2020/04/14 Python
纯CSS3发光分享按钮的实现教程
2014/09/06 HTML / CSS
性能测试工程师的面试题
2015/02/20 面试题
电子商务专业学生的学习自我评价
2013/10/27 职场文书
简历自荐信
2013/12/02 职场文书
办公室经理岗位职责
2014/01/01 职场文书
高中军训感言800字
2014/03/05 职场文书
向领导表决心的话
2014/03/11 职场文书
《会走路的树》教后反思
2014/04/19 职场文书
2014年反洗钱工作总结
2014/11/22 职场文书
违反学校规则制度检讨书
2015/01/01 职场文书
通知怎么写?
2019/04/17 职场文书
个人房屋租赁合同(标准范本)
2019/09/16 职场文书