PHP如何实现同一个帐号不允许同时登陆?

free212 2009-07-12 12:58:31
一个会员系统,要实现的要求为:

当一个帐号登陆后,不允许相同的帐号再次登陆,提示该帐号已经登陆或挤掉上一个已登陆的用户。


因流量较大,务求用最简洁、高效的方法,环境为:PHP5.1/MYSQL5.1/SESSION为文件存储。

请高手指点,谢谢!
...全文
1986 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
ruxingli 2011-03-23
  • 打赏
  • 举报
回复
出vbc1
D_Mars 2010-07-09
  • 打赏
  • 举报
回复
菜鸟路过...
个人觉得可以用PHP+TXT的小技巧..
maxmas 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 wxq4100798 的回复:]
汗啊,搞了半天,居然都是一帮菜鸟在讨论,无视我的答案,郁闷
[/Quote]

你丢一句话人就闪了,难怪没人理你,
如果大家懂FLASH xmlsocket,早就有人提出来了,
还需要在这边讨论半天吗,既然自认老鸟,本来就应该讲清楚,
否则依老卖老,没负起教育的责任,谁会尊重你啊
wxq4100798 2009-08-28
  • 打赏
  • 举报
回复
汗啊,搞了半天,居然都是一帮菜鸟在讨论,无视我的答案,郁闷
sunshinexrain 2009-07-16
  • 打赏
  • 举报
回复
方法:

数据库表 user_login_info
字段:id,user_ip,user_id,last_access_time

user_id 做唯一性索引


1. 用户登录后
如果没有当前用户的数据,插入一条数据,user_ip(用户机器的IP),user_id(用户ID),last_access_time(当前登录时间)
如果已经存在,则更新 user_ip,last_access_time 2个字段

2. 如何判断?
另一个用户,如果用相同的账号
1)在同一台机器上再次登录的情况 【ip相同】,直接更新这个用户的 last_access_time 时间为最新时间就可以了。

处理:直接更新 last_access_time 为最新时间

2)在另外一台机器上登录的情况【ip不同】,根据user_id取出数据,判断ip和last_access_time(上次登录时间),
如果当前时间 now()-last_access_time < 10 (分钟) 【这里是关键,设置一个时间】,说明有人在其他机器上已经登录了,则不允许登录。
now()-last_access_time > 10 (分钟) ,则可以登录,说明另一个人要不已经有10分钟没有活动了,要不就是没登陆,这2种情况下都允许重新登录。

3. 在程序的入口文件 index.php (ZF框架参考),每次用户登录后的操作,都更新 last_access_time 时间为最新时间 (这个也许效率上需要考虑一下,其实也应该没什么问题,数据库完全可以承受,也可以在程序里加上一个判断,last_access_time 时间存在 session里,如果这个时间跟当前时间 date() 比较,超过设定的10分钟时间,则更新数据库 last_access_time 字段。这样可以减少更新数据库的次数)

4. 异常退出的情况,比如用户直接关闭浏览器,数据库里还有这条记录,因为设置的过期时间是10分钟,所以如果同一个用户立刻再次登录的情况下,肯定不行,会提示已经有人登陆了。但10分钟后就可以再次登录,所以这个10分钟时间看具体情况,可以设置成 1分钟,或其他时间。
但这个时间不要设置成几个小时,那用户会疯掉。


原理:就是设置一个过期时间的技巧和记录IP。


不知道这样做,是否是能满足lz的要求。



free212 2009-07-16
  • 打赏
  • 举报
回复

感谢各位的回复,考虑到效率及简易性,最后采用了6楼yctin的方法并结合了其它几位的建议,实现过程如下:

一,会员表加一个字段(last_session),会员登陆时获取当前SESSIONID更新此字段。

二,会员登陆时取得该(last_session)值去session_save_path看该文件有没有,如有则直接删除。

三,假如有两个人以上同时使用的话,那么前一个的会话文件就会被后面的一个所删除,也就被逼下线了。


这样也就达到了每次只能一个帐号使用的目的了,虽然用户体验略差,但也算是较高效的方法了。

再次感谢各位的建议,这个方法或许不是最好的,但至少解决了我的当务之急,当然更期待有更好的方法。
testoktest 2009-07-16
  • 打赏
  • 举报
回复
当一个帐号登陆后,不允许相同的帐号再次登陆,
1.提示该帐号已经登陆
2.或挤掉上一个已登陆的用户。

简单啊,a1用a帐号登陆后,在个公共的地方记录,a帐号使用中。数据库/文本
a2用a帐号登陆时,看看公共记录有没有a使用,有就提示
如果挤掉,
a1登陆除了记录使用,还记录一个唯一号,每次操作时,都验证这个唯一号是否和会话中保存的一样,不一样,就说明被挤掉了
楼上有说道,a2登陆时,直接删除a1的会话session,但这还是得a2要知道a1的session_id,如何知道?必须记录到一个公共地方
------
如果是1,提示该帐号已经登陆,那么a2什么时候可以登陆?就要约束一个不操作的刷新时间,比如20分钟,认为吊线/自动退出,那么公共地方还要记录,a1用户最后一次操作时间
潇湘博客 2009-07-16
  • 打赏
  • 举报
回复
添加一个用户登录表。通过这个表判断用户的状态。
free212 2009-07-16
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 Dean_L 的回复:]
呵呵 有这么麻烦吗?
用二楼的方法就行了 没有必要在数据库添加字段

换一种思路 用session的KEY来保存用户ID 判断该ID session 的值为OK或空 来表示该ID是否在线
示例代码:

PHP code
//登录判断
session_start();
if(session_is_registered($用户ID))
{
echo "该用户已经登录!";
}
else
{
$_SESSION[$用户ID] = "OK";
echo "登录成功!";
}

如果用上面说的AJAX判断的话 流量少还是可以 等流量大 服…
[/Quote]

这是不合理的,session_is_registered只是针对当前会话,而每次新开浏览器或是不同浏览器 SESSIONID是不一样的,
free212 2009-07-16
  • 打赏
  • 举报
回复
[Quote=引用 47 楼 xinhui24 的回复:]
方法:

数据库表 user_login_info
字段:id,user_ip,user_id,last_access_time

user_id 做唯一性索引

1. 用户登录后
如果没有当前用户的数据,插入一条数据,user_ip(用户机器的IP),user_id(用户ID),last_access_time(当前登录时间)
如果已经存在,则更新 user_ip,last_access_time 2个字段
[/Quote]

谢谢,谢谢你这么用心的写了这个过程,也是个不错的思路,理论上是可行的。
但也有点小问题,一是这样的判断不大精准,二是也要频繁的操作数据库,我希望的是能尽量的减少对数据库的操作。
xiefeng209 2009-07-16
  • 打赏
  • 举报
回复
我是来学习的!期待答案
hjzhangjing1 2009-07-16
  • 打赏
  • 举报
回复
不在同一台机器的话 应该还是要存入数据库1个字段还可以给定一个时间,对于非正常关闭时(每次登陆)可以在用户登陆时判断1下 判断上次登陆时间如果>一个时间 那么就清空上次登陆状态 成功做到此次登陆
raid79 2009-07-16
  • 打赏
  • 举报
回复
mark
yagas 2009-07-16
  • 打赏
  • 举报
回复
把session写进数据库中。登陆之前可以进行判断是否已经登陆。
qroom 2009-07-16
  • 打赏
  • 举报
回复
我觉得6楼和18楼的方面就能解决问题,都是得用SESSION,好像比较稳妥。
free212 2009-07-15
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 yctin 的回复:]
我那段东西已经有你想要的...你看不明白就算吧...
我没空一步步写方法
[/Quote]

挤掉上一个已登陆的用户:
用户表加一个字段(last_session), 或加一个新表(user_id, last_session)
当同一个用户登入时
取得上一次的session id 并删除该id的内容
再更新成新的 session id

-------------------------------------------

你好yctin ,可是指这一段吗?
我还是没能明白你的这个思路,能否请你就上面的说法再讲解一下吗?有劳
ruanchao 2009-07-15
  • 打赏
  • 举报
回复
挤掉上一个已登陆的用户 --> 单一登陆


提示该帐号已经登陆 --> 这个暂时,恐怕还没有什么精确的解法。
villainme 2009-07-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 yctin 的回复:]
挤掉上一个已登陆的用户:
用户表加一个字段(last_session), 或加一个新表(user_id, last_session)
当同一个用户登入时
取得上一次的session id 并删除该id的内容
再更新成新的 session id

提示该帐号已经登陆:
用户表加2个字段(last_access,last_session), 或加一个新表(user_id,last_access ,last_session)
当同一个用户登入时
取得上一次的last_access time,session id
如果最后存取时间过久, 清除该session , 换新…
[/Quote]


我觉得这个可行,异常退出时如果是多线程浏览器,最坏的情况就是SESSION在20分钟左右不会失效,一般的只要浏览器关闭SESSION就会失效,因此只需要判断SESSION是否存在就可以得到帐号的登录状态了

答案来源:http://www.php0731.cn/index.php?news-content.html&id=425
free212 2009-07-15
  • 打赏
  • 举报
回复
我也是快晕掉了,高手们都不愿多说。这的确是个难题,搜索了一天都没找到合适的解决方案。
Ricky_Bobo 2009-07-15
  • 打赏
  • 举报
回复
我都看晕掉了,怎么都答得天南地北?等出了答案楼主给说一声哦,我来看看怎么个正解法.
加载更多回复(40)

21,891

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧