基于PHP實(shí)現(xiàn)一個(gè)簡(jiǎn)單的在線聊天功能
要實(shí)現(xiàn)功能,首先要做前端,經(jīng)過(guò)對(duì)比其他網(wǎng)站的在線聊天功能,發(fā)現(xiàn)除了基本的聊天功能以外,還要注意以下幾點(diǎn).
一次只能和一個(gè)人聊天,但是可以隨意切換其他人. 如果用戶是從'發(fā)送消息' 入口進(jìn)來(lái)的,那么當(dāng)前馬上就切換到對(duì)應(yīng)的聊天窗口,而且如果之前有過(guò)聊天記錄,應(yīng)該把聊天記錄也展示出來(lái). 如果是從'我的消息' 入口進(jìn)來(lái)的,那么應(yīng)該不顯示任何聊天記錄.等待選擇聊天對(duì)象. '我'發(fā)送的消息顯示在右邊,'對(duì)方'發(fā)送的消息顯示在左邊,也可以相反,總之要不一樣. 切換聊天的時(shí)候不能刷新整個(gè)頁(yè)面,否則體驗(yàn)很差. 發(fā)送消息也同理,所以應(yīng)該用ajax 要保證在線聊天的及時(shí)性,應(yīng)該每隔一段很短的時(shí)間,就要與服務(wù)端通信,也就是說(shuō)要輪詢ajax.前端頁(yè)面經(jīng)過(guò)簡(jiǎn)單的需求分析,然后又找了找其他的網(wǎng)站,對(duì)比了一下功能在界面的展示,最終確定界面. 然后花了幾個(gè)小時(shí)做好了.
成品
這是最終全部做完(包括后端) 的效果.
點(diǎn)擊左側(cè)可以切換,下方多行文本框,輸入聊天信息,然后點(diǎn)擊發(fā)送.
整個(gè)流程大概就是這樣.
數(shù)據(jù)庫(kù)回頭來(lái)看需求, 很明顯,首先要有一張表格,存放雙方的對(duì)話,想了想決定這樣定義字段:
主要是這兩個(gè)字段: user_id 表示消息發(fā)送的主體 chat_user 表示消息接收的主題
這樣定義的好處是,可以輕易從一條消息中輕易辨別哪個(gè)是發(fā)送方,哪個(gè)是接收方,為前端的展示做準(zhǔn)備.
但是這樣還不夠
有了這張表,就可以通過(guò)當(dāng)前登錄的session中的用戶ID, 去進(jìn)行查詢,可以得知在跟哪些人聊天. 但是這樣并不方便,而且要進(jìn)行復(fù)雜的處理.
假設(shè)有一條消息是己方發(fā)送的,那么就插入數(shù)據(jù) ‘己方’ ‘對(duì)方’ ‘內(nèi)容’,同時(shí)可以知道當(dāng)前聊天中的一個(gè)人是’對(duì)方’. 但是假設(shè)有一條消息是對(duì)方發(fā)送的,對(duì)當(dāng)前用戶來(lái)說(shuō),數(shù)據(jù)就是 ‘對(duì)方’ ‘己方’ ‘內(nèi)容’.也就是說(shuō),想要實(shí)現(xiàn)多人聊天,就要獲取當(dāng)前正在跟 ‘我’ 聊天的用戶們.不論是對(duì)方發(fā)送的,還是 ‘我’ 發(fā)送的,都應(yīng)該計(jì)算在內(nèi). 要對(duì)數(shù)據(jù)庫(kù)遍歷兩次,而且很多對(duì)當(dāng)前來(lái)說(shuō)是重復(fù),無(wú)用的數(shù)據(jù). 在”獲取聊天對(duì)方的主體” 這一步時(shí), 只需要知道兩個(gè)人是否有聊天關(guān)系即可,具體內(nèi)容不用關(guān)心.
所以還要一張聊天關(guān)系表. 我是這樣定義字段的:
其中user_id 和 chat_user 為雙主鍵,不能同時(shí)相等. 這樣就只記錄了聊天關(guān)系,不記錄聊天內(nèi)容,搜索起來(lái)也方便得多. ‘我’ 是user_id ‘對(duì)方’ 是chat_user
舉個(gè)例子 第一個(gè)字段表示 我與ID為9的用戶 有一個(gè)聊天關(guān)系, 所以在’我’的界面上,就應(yīng)該有這個(gè)用戶. 同理 第二條字段表示 對(duì)方與我有聊天關(guān)系,那么在對(duì)方的界面上,就要有我這個(gè)用戶.
一般來(lái)說(shuō)聊天關(guān)系是相互的, 但是也可以刪除. 刪除聊天關(guān)系并不等于刪除聊天記錄. 比如,在我的界面上,我把與9號(hào)用戶的聊天關(guān)系刪除了,那么我就看不到與9號(hào)用戶的聊天信息了, 但是對(duì)9號(hào)用戶來(lái)說(shuō),我還在他的界面上,隨時(shí)可以向我發(fā)送消息. 當(dāng)他向我發(fā)送消息時(shí),服務(wù)端又要生成一條數(shù)據(jù) ‘我’ ‘對(duì)方’ ,這樣,我與對(duì)方的聊天關(guān)系又建立起來(lái)了,同時(shí),聊天記錄一直都沒(méi)有被刪除過(guò),所以,當(dāng)重新建立聊天關(guān)系時(shí),可以展示出聊天記錄.
而且,刪除聊天關(guān)系后, 我也可以重新發(fā)起聊天, 再次建立聊天關(guān)系. 所以這張表建立之后提供很多方便, 上面分析的需求,展示聊天記錄,也可以很好的完成.
實(shí)現(xiàn)思路首先,主要功能有一個(gè)控制器,兩張表,兩個(gè)模型. 至于頭像,昵稱什么的,不計(jì)算在主要功能內(nèi).
控制器MessageController 一共有五個(gè)方法.
1.showPage()用來(lái)應(yīng)對(duì)非ajax請(qǐng)求,用戶通過(guò)瀏覽器訪問(wèn)時(shí),比如第一次進(jìn)入聊天界面,就是通過(guò)瀏覽器訪問(wèn)的,這時(shí)候調(diào)用showPage方法,這時(shí)候,后臺(tái)只獲取聊天關(guān)系(第四個(gè)方法),展示在界面左側(cè). 其他不作處理.
2.newChat()用來(lái)應(yīng)對(duì)非ajax請(qǐng)求, 比如我通過(guò)用戶個(gè)人資料頁(yè)面,點(diǎn)擊發(fā)送消息,這時(shí)候就調(diào)用這個(gè)方法. 先判斷聊天關(guān)系是否存在,如果存在就不處理,如果不存在,就插入一個(gè)聊天關(guān)系. 并且要獲取所有聊天關(guān)系(第四個(gè)方法),最新的排上面,把用戶ID轉(zhuǎn)到界面上.為后面做準(zhǔn)備.
3.getChatText()用來(lái)應(yīng)對(duì)ajax請(qǐng)求. 用來(lái)獲取聊天信息. ‘我’ 這個(gè)用戶來(lái)到聊天界面上后, 前端就開(kāi)始進(jìn)行ajax輪詢.不停訪問(wèn)getChatText()這個(gè)方法. 這時(shí)有兩種情況.
當(dāng)前正在與某個(gè)用戶聊天,js就發(fā)送一個(gè)請(qǐng)求到getChatText方法,參數(shù)是對(duì)方的用戶ID. 因?yàn)椤摇腎D 可以從服務(wù)端session獲取到.然后通過(guò)這兩個(gè)信息去數(shù)據(jù)庫(kù)獲取聊天消息.返回json格式,js進(jìn)行數(shù)據(jù)處理,節(jié)點(diǎn)操作,等等,然后把消息展示出來(lái). 當(dāng)前沒(méi)有正在與某個(gè)用戶聊天,那ajax暫不啟動(dòng),當(dāng)選擇了聊天對(duì)象的時(shí)候再啟動(dòng)輪詢.4.getChatTemp()獲取當(dāng)前登錄用戶的聊天關(guān)系. 作為一個(gè)工具函數(shù),供第一個(gè)和第二個(gè)函數(shù)使用.
5.pushChat()用來(lái)應(yīng)對(duì)ajax請(qǐng)求, 也就是發(fā)送消息請(qǐng)求. 把聊天消息插入數(shù)據(jù)庫(kù)而已.
總結(jié)實(shí)現(xiàn)了在線聊天的基本功能,但是有缺陷, 獲取聊天消息的時(shí)候,我是無(wú)論有沒(méi)有新消息,都全部獲取到. 然后清空聊天框,再填充. 這樣的結(jié)果是, 當(dāng)聊天信息很多的時(shí)候,滾動(dòng)條會(huì)有問(wèn)題, 每次發(fā)送消息,滾動(dòng)條都會(huì)先滾動(dòng)到最上面,再滾動(dòng)下來(lái). 有個(gè)解決方案是,在聊天關(guān)系上加一個(gè)字段,存儲(chǔ)兩個(gè)人的消息數(shù). 獲取完數(shù)據(jù)的時(shí)候,先統(tǒng)計(jì)一下,看看是不是比原來(lái)的多了,如果多了,就只獲取多的數(shù)據(jù),然后更新消息數(shù)目. 如果沒(méi)多,那就舍棄數(shù)據(jù),不做處理.
以上就是基于PHP實(shí)現(xiàn)一個(gè)簡(jiǎn)單的在線聊天功能的詳細(xì)內(nèi)容,更多關(guān)于PHP在線聊天的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. php網(wǎng)絡(luò)安全中命令執(zhí)行漏洞的產(chǎn)生及本質(zhì)探究2. 三個(gè)不常見(jiàn)的 HTML5 實(shí)用新特性簡(jiǎn)介3. Angular獲取ngIf渲染的Dom元素示例4. IIS+PHP添加對(duì)webp格式圖像的支持配置方法5. ASP調(diào)用WebService轉(zhuǎn)化成JSON數(shù)據(jù),附j(luò)son.min.asp6. 無(wú)線標(biāo)記語(yǔ)言(WML)基礎(chǔ)之WMLScript 基礎(chǔ)第1/2頁(yè)7. 使用.net core 自帶DI框架實(shí)現(xiàn)延遲加載功能8. Warning: require(): open_basedir restriction in effect,目錄配置open_basedir報(bào)錯(cuò)問(wèn)題分析9. php測(cè)試程序運(yùn)行速度和頁(yè)面執(zhí)行速度的代碼10. ASP.NET Core 5.0中的Host.CreateDefaultBuilder執(zhí)行過(guò)程解析
