' .
$_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;
}
?>