逆向思维在项目开发中真的很重要
最近一直和我的小组开发一个投资类型的网站,网站的整体已经完成得差不多了,客户今天突然提出了一个要求,希望能够在所有人退出当前聊天大厅后,后面进入的人不能够看到之前用户的聊天记录(原来是可以看到的)。由于聊天室代码是别人写的,且基本算木有注释,也木有相关的文档。研究源码太耗时间了,由于聊天数据比较小,聊天室窗口是从messages表中读取的数据,所以打算当用户退出时,执行某一机制将Ajax_chat_messages表中对应聊天室的数据copy到一个新的Chat_messages表中,同时清除Ajax_chat_messages表中这部分数据。
由于先入为主的思维定式,一直想的是当最后一个用户退出该聊天大厅后,应该采取一个机制达到这一目的。所以打算通过php的igonre_user_abort()和set_time_limit()函数每隔一段时间执行某一段代码,来检查online(在线用户表)表,查看该大厅是否没有用户了。然而这样的话一是如果前面的用户在函数执行间期退出,新用户也在这个时候登陆,这样这个函数原来的初衷就无法达到,再就是每隔一段时间就对数据库进行查询有点浪费资源。不过我还是尝试了一把^_^:
ignore_user_abort(); // 后台运行 set_time_limit(0); // 永远执行 $interval=60*1; // 每分钟执行一次 $start = 1; $chat = M('Messages'); do{ $start += 2; $data['userID']='1'; $data['userName']='user'; $chat->add($data); sleep($interval); }while(true);
程序一直在向数据表中插入数据了,嗯,还不错!可是当我想停止的时候,悲剧了!我删除了这段代码,程序在运行,清除缓存关闭浏览器,程序也没停止,还在向数据库添加数据,最后直到我重启了Apache服务器,程序才停止。汗!如果数据量大,估计我数据库就要熄火了。感觉这个自动的东西还是比较危险的,需要精确的控制,稍有不慎就会造成很严重的后果,还是触发机制比较好,我要用了才执行你,不用的时候你就乖乖的在旁边呆着。唉~话痨病又犯了!-_-!!!
左思右想,也没想出个可以确定用户全部退出的好法子。突然(有时候就是这么突然)灵光一闪,既然我确定不了所有用户退出的确切的时间,但是我可以确定每个用户登录的时间啊(用户在进入聊天大厅的时候要在验证界面输入一遍大厅的密码)。于是我在用户进入验证界面的时候调用了下面的函数,先判断大厅里是否有人,如果没有,视为第二次进入,触发预订机制把前一次的聊天记录copy到chat_messages,并清除原表里对应大厅的聊天数据。问题解决。
1 //这里判断先判断大厅是否有人,如果没有视为第二次进入, 2 //则触发预订机制把前一次的聊天记录cp到tr_chat_messages,并清除原表里对应大厅的聊天数据 3 public function cpMessage($channel){ 4 $m = M('Ajax_chat_online'); 5 $chat = M('Ajax_chat_messages'); 6 $newchat = M('Chat_messages'); 7 $arr = $m->where('channel='.$channel)->select(); 8 if($arr == null){ 9 $res = $chat->where('channel='.$channel)->order('dateTime desc')->select(); 10 for($i=0;$i<count($res);$i++){ 11 $a = $newchat->add($res[$i]); 12 if($a){ 13 $chat->where('channel='.$channel)->delete(); 14 } 15 } 16 } 17 }
当然,这是取巧了,如果聊天大厅数据量庞大的话,这样做就不可取了。但是解决问题是前提,这里我想说的是在遇到问题的时候,换个思路,也许问题就能迎刃而解。记在这里,也提醒着自己在未来不要忘了这灵光一闪的感触。更优的法子等得空了再来想。