' . $_SESSION['username'] . ' 進入聊天室
'; // $_SESSION['lastRead'] 記錄最近一次讀到的訊息之索引 // addMsg() 會傳回加入的新訊息所在位置之索引 // 以下設定新使用者從歡迎自己的訊息開始讀取 $_SESSION['lastRead'] = addMsg($welcomeMsg); unset($_SESSION['newuser']); // 取消新使用者狀態 } // 若 $_SESSION['newuser'] 不是 true // 也沒有 $_SESSION['lastRead'] 的值 // 表示使用者是隨意進入聊天室, 因此轉至登入網頁 elseif(!isset($_SESSION['lastRead'])) // 隨意進入本網頁 header('Location: EnterRoom.php'); // 轉至登入網頁 require_once ("../xajax_core/xajax.inc.php"); // 引用 xajax 類別 $xajax = new xajax(); // 建立物件 $xajax->registerFunction('send'); // 註冊送出訊息的回應函式 $xajax->registerFunction('read'); // 註冊讀取訊息的回應函式 $xajax->registerFunction('bye'); // 註冊離開聊天室的回應函式 $xajax->processRequest(); // 處理非同步要求 // -------------------------------------------------------------------- // 新增訊息至聊天檔的函式, 傳回值為新訊息存於陣列的索引值 function addMsg($msg) { // 檢查聊天檔案是否存在 if(is_file(CHAT_FILE)) // 若檔案存在 $msgEntry = unserialize(file_get_contents(CHAT_FILE)); else // 若檔案不存在 $msgEntry[0] = ENTRY_MAX; // 將代表最後一筆資料位置的變數 // 設到最後一筆 $indexLast = $msgEntry[0]; // 保留最後一筆的數值, 以便稍後傳回 if(++$msgEntry[0] > ENTRY_MAX) // 將代表最後一筆資料位置的變數加 1 $msgEntry[0] = 1; // 若其值超過訊息數上限, 則設為 1 $msgEntry[$msgEntry[0]] = $msg; file_put_contents(CHAT_FILE, serialize($msgEntry), LOCK_EX); return $indexLast; // 傳回新加入訊息所在的索引值 } // 只有新進聊天室時, 會用到此傳回值 // 接收用戶端送出新訊息的回應函式 function send($aFormValues) { // 參數為表單陣列 // 由表單陣列取得使用者輸入的訊息、及選擇的訊息顏色 $usermsg = htmlspecialchars($aFormValues['usermsg']); $colorselect = $aFormValues['colorselect']; // 組合訊息字串, 在字串最後加上換行標籤 $str = sprintf('[%s] %s:%s
', date('H:i:s'), // 目前時間 $_SESSION['username'], // 使用者暱稱 $colorselect, // 訊息顏色 changeface($usermsg)); // 替換表情字串後的訊息文字 addMsg($str); // 將訊息存檔 $objResponse = new xajaxResponse(); return $objResponse; // 傳回空的回應內容 } // 將表情符號置換成對應圖檔 img 標籤的函式 function changeface($str) { // 表情符號陣列 $symbols = array(':)', ':(', ':D', ':cry'); // 表情圖案檔名陣列 $tags = array('', '', '', ''); // 將 $str 中出現的 $symbols 陣列元素, 換成對應的 $tags 陣列元素 return str_replace($symbols, $tags, $str); } // 由用戶端定時呼叫, 以便讀取新的聊天訊息的回應函式 function read() { $objResponse = new xajaxResponse(); if(!is_file(CHAT_FILE)||!is_file(USER_LIST)) { // 若檔案不存在 $objResponse->append('allmsg', 'innerHTML', // 在網頁中顯示訊息 '系統錯誤'); $objResponse->call('scrollDiv',null); return $objResponse; } $users = unserialize(file_get_contents(USER_LIST)); // 讀取名單 $msgEntry = unserialize(file_get_contents(CHAT_FILE)); // 讀取訊息 $indexLast = $msgEntry[0]; // 比較用戶端上次讀到的訊息索引, 與目前檔案記錄最後一筆訊息的索引 // 兩者相同表示沒有新訊息要傳送給用戶端, 即跳過 if 段落 // 兩者不同才需傳送新訊息給用戶端 if ($_SESSION['lastRead'] != $indexLast) { $str = ''; // 初始化訊息字串 // 由最近一筆訊息開始往前讀, 讀到上次所讀到的訊息為止 for($i=$indexLast; $i != $_SESSION['lastRead']; ) { $str = $msgEntry[$i] . $str; // 以『舊訊息在前』的方式串接訊息 ($i == 1) ? $i = ENTRY_MAX : // 若 $i==1, 將 $i 設為索引最大值 $i--; // 否則將 $i 值減 1 } $_SESSION['lastRead'] = $indexLast; // 更新 session 中的記錄 $objResponse->append('allmsg', 'innerHTML', $str); // 回應訊息 // 呼叫捲動訊息區的 JavaScript 函式 $objResponse->call('scrollDiv'); } // 將目前的使用者名單存到 $nameList 字串 $nameList = ''; foreach($users as $k=>$username) $nameList .= $username . '
'; $objResponse->assign('userlist', 'innerHTML', $nameList); // 傳回名單 return $objResponse; } // 用戶離線的回應函式 function bye() { $users = unserialize(file_get_contents(USER_LIST)); // 取得名單陣列 // 將使用者暱稱自名單移除 unset($users[strtolower($_SESSION['username'])]); if(count($users) == 0) { // 若聊天室已沒有人了 unlink(USER_LIST); // 刪除名單檔 unlink(CHAT_FILE); // 刪除聊天檔 } elseif (isset($_SESSION['username'])) { // 若聊天室還有別人 // 將減少一人的名單陣列寫回名單檔 file_put_contents(USER_LIST, serialize($users), LOCK_EX); // 建立一筆使用者離開的訊息 $byeMsg = '' . $_SESSION['username'] . ' 離開聊天室
'; addMsg($byeMsg); // 新增訊息 } session_destroy(); // 清除 session 變數 $objResponse = new xajaxResponse(); $objResponse->redirect('EnterRoom.php'); // 將使用者轉回登入網頁 return $objResponse; } ?> 聊天室 printJavascript('..'); // 輸出 xjajx 用戶端程式碼 ?>

暱稱: 暫停捲動
發言: