基于PHP实现用户在线状态检测

这篇文章主要介绍了基于PHP实现用户在线状态检测,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下。

这个是基于ThinkPHP框架的,其他的可以自己根据需求改

1.先新建一个tags.php文件,放在配置目录Conf下。

  1. <?php
  2. /*
  3. * 添加行为
  4. *
  5. */
  6. return array(
  7. 'action_begin' => array('OnlineCheck'),
  8. );
  9. ?>

2.定义具体的功能

  1. <?php
  2. /*
  3. * 定义行为: 在线更新
  4. */
  5. class OnlineCheckBehavior extends Behavior {
  6. //行为参数
  7. protected $options = array(
  8. 'ONLINE_CHECK' => true, // 默认进行在线
  9. 'ONLINE_CHECK_TIME' => 10, // 默认5分钟未活动,说明已下线
  10. );
  11. public function run(&$params) {
  12. if (C('ONLINE_CHECK')) {
  13. // 更新session
  14. if ((session('?login_account')) && (time() - session('access_time') > 60)) {
  15. session('access_time', time());
  16. }
  17. // 在线更新
  18. $ip = ip2long(get_client_ip());
  19. $online = M('Online');
  20. // 先删除在线表中 超过5分钟未活动的记录
  21. //$sql = ' delete from __TABLE__ where ';
  22. $map['lasttime'] = array('lt', time() - C('ONLINE_CHECK_TIME') * 60);
  23. $icount = $online->where($map)->delete();
  24. if (session('?login_account')) { // 如果是登录用户
  25. $map = array();
  26. $map['uid'] = session('login_uid');
  27. $map['lastip'] = $ip;
  28. $id = $online->where($map)->getField('id');
  29. if (emptyempty($id)) { // 不存在在线记录,则清空session
  30. session(null);
  31. } else {
  32. $map = array();
  33. $map['id'] = array('eq', $id);
  34. $data['lasttime'] = time();
  35. $data['lastip'] = $ip;
  36. $online->where($map)->save($data);
  37. }
  38. } else { // 不是登录用户 游客
  39. unset($map);
  40. $map['lastip'] = array('eq', $ip);
  41. $id = $online->where($map)->getField('id');
  42. //dump($id);
  43. if (emptyempty($id)) { // 不存在在线记录, 则添加
  44. $data = array();
  45. $data['uid'] = 0;
  46. $data['account'] = 'Guest';
  47. $data['nickname'] = '游客';
  48. $data['lasttime'] = time();
  49. $data['lastip'] = $ip;
  50. $online->add($data);
  51. } else {
  52. $map = array();
  53. $map['id'] = array('eq', $id);
  54. $data['lasttime'] = time();
  55. $data['lastip'] = $ip;
  56. $online->where($map)->save($data);
  57. }
  58. }
  59. }
  60. }
  61. }
  62. ?>

3.在具体的登录方法上添加:

  1. // 登录检测
  2. public function checkLogin() {
  3. // $this->redirect($url);
  4. $username = strtolower($this->_param('usr'));
  5. $pwd = $this->_param('pwd');
  6. $url = $this->_param('url'); // 目标地址
  7. $is_error = false;
  8. if (emptyempty($username) or emptyempty($pwd)) {
  9. $this->assign('error_msg', '用户名和口令不能为空');
  10. $is_error = true;
  11. }
  12. if (!$is_error) {
  13. $model = M('Usr');
  14. $map['account'] = $username;
  15. $map['upwd'] = strtoupper(md5($pwd));
  16. $icount = $model->where($map)->count();
  17. if ($icount == 1) {
  18. $list = $model->where($map)->find();
  19. // 检测用户是否在线
  20. if ($this->isOnline($list['id'])) {
  21. // <editor-fold defaultstate="collapsed" desc="if开始">
  22. if ($list['status']) {
  23. session('login_account', $username);
  24. session('login_nickname', $list['nickname']);
  25. session('last_time', toDate($list['last_time']));
  26. if ($list['last_ip']) {
  27. session('last_ip', long2ip($list['last_ip']));
  28. } else {
  29. session('last_ip', get_client_ip());
  30. }
  31. session('login_count', $list['login_count']);
  32. session('login_uid', $list['id']);
  33. session('login_pwd', $list['upwd']);
  34. session('access_time', time()); //用户最后点击页面时间 session超时使用
  35. ///
  36. $map['id'] = $list['id'];
  37. $data['last_time'] = time();
  38. $data['last_ip'] = ip2long(get_client_ip());
  39. $model->where($map)->save($data);
  40. $model->where($map)->setInc('login_count', 1);
  41. // 检测是否有同一IP的记录,有更新,否则 添加
  42. $online = M('Online');
  43. $map = array();
  44. $map['lastip'] = ip2long(get_client_ip());
  45. $online_id = $online->where($map)->getField('id');
  46. if (emptyempty($online_id)) {
  47. // 插入在线用户表
  48. $data = array();
  49. $data['uid'] = $list['id'];
  50. $data['account'] = $list['account'];
  51. $data['nickname'] = $list['nickname'];
  52. $data['lasttime'] = time();
  53. $data['lastip'] = ip2long(get_client_ip());
  54. $online->add($data);
  55. }else{
  56. // 更新在线用户表
  57. $data = array();
  58. $data['uid'] = $list['id'];
  59. $data['account'] = $list['account'];
  60. $data['nickname'] = $list['nickname'];
  61. $data['lasttime'] = time();
  62. //$data['lastip'] = ip2long(get_client_ip());
  63. $online->where($map)->save($data);
  64. }
  65. } else {
  66. $is_error = true;
  67. $this->assign('error_msg', '此用户已被禁止登录!');
  68. }
  69. // </editor-fold> if 结束
  70. } else {
  71. $is_error = true;
  72. $this->assign('error_msg', '此用户名已在其他电脑登陆,请' . C('ONLINE_CHECK_TIME') .'分钟后再试!');
  73. }
  74. } else {
  75. $is_error = true;
  76. $this->assign('error_msg', '错误的用户名或口令!');
  77. }
  78. }
  79. if ($is_error) {
  80. $this->display('login');
  81. } else {
  82. $this->redirect('Index/index');
  83. // if (empty($url)) {
  84. // $this->redirect('Index/index');
  85. // } else {
  86. // $this->redirect($url);
  87. // }
  88. }
  89. }
  90. /**
  91. * 检测用户是否在线
  92. * @access private
  93. * @param int $uid 用户ID
  94. * @return Boolean true=不在线
  95. */
  96. private function isOnline($uid) {
  97. $ip = ip2long(get_client_ip());
  98. $online = M('Online');
  99. $map['uid'] = array('eq', $uid);
  100. $list = $online->where($map)->find();
  101. if (emptyempty($list)) { // 不存在
  102. return true;
  103. } else { // 存在,检测IP是否一致,否则,检测是否超过5分钟
  104. if ($list['lastip'] == $ip) {
  105. return true;
  106. } else {
  107. if ($list['lasttime'] < time() - C('ONLINE_CHECK_TIME') * 60) {
  108. return true;
  109. } else {
  110. return false;
  111. }
  112. }
  113. }
  114. }

以上就是具体的PHP在线状态检测,同一时间只有一个用户可以存在,不过还没有考虑到非正常掉线等,cookie,session意外的处理,但是先分享出来吧。