四文件架構
login.php:選擇房間、輸入暱稱
chat.php:框架頁,分上下兩框架
view.php:顯示訊息(自動刷新)
input.php:發送訊息表單
- 數據文件:
1.txt 大廳、2.txt 客房、3.txt 後院
核心代碼
login.php
<form action="chat.php">
房間:
<select name="room">
<option value="大廳">大廳</option>
<option value="客房">客房</option>
<option value="後院">後院</option>
</select>
暱稱:<input type="text" name="name">
<input type="submit" value="進入">
</form>
chat.php(框架集)
<frameset rows="80%,*">
<frame src="view.php?room=<?php echo urlencode($room); ?>">
<frame src="input.php?name=<?php echo urlencode($name); ?>&room=<?php echo urlencode($room); ?>">
</frameset>
view.php(顯示 + 自動刷新)
<meta http-equiv="refresh" content="5; url=view.php?room=<?php echo urlencode($room); ?>">
<?php
$roomFiles = [
'大廳' => '1.txt',
'客房' => '2.txt',
'後院' => '3.txt',
];
$file = $roomFiles[$room] ?? '0.txt';
$chat_length = 25; // 顯示最近 25 行
$lines = file($file, FILE_IGNORE_NEW_LINES);
$start = max(0, count($lines) - $chat_length);
for ($i = $start; $i < count($lines); $i++) {
echo htmlspecialchars($lines[$i]) . '<br>';
}
?>
input.php(發送表單)
<form action="send.php" method="post" target="view_frame">
<input type="hidden" name="room" value="<?php echo htmlspecialchars($room); ?>">
<input type="hidden" name="name" value="<?php echo htmlspecialchars($name); ?>">
訊息:<input type="text" name="msg">
<input type="submit" value="發送">
</form>
send.php(寫入處理)
<?php
$room = $_POST['room'];
$name = $_POST['name'];
$msg = $_POST['msg'];
$roomFiles = [
'大廳' => '1.txt',
'客房' => '2.txt',
'後院' => '3.txt',
];
$file = $roomFiles[$room] ?? '0.txt';
$entry = date('H:i:s') . " [$name] $msg\n";
$f = fopen($file, 'a');
if (flock($f, LOCK_EX)) {
fwrite($f, $entry);
flock($f, LOCK_UN);
}
fclose($f);
?>
關鍵技術點
- Frameset 架構:上框顯示(自動刷新),下框輸入,避免整頁重載
- 文件鎖:
flock(LOCK_EX) 保證併發寫入不丟數據
- XSS 防護:輸出時
htmlspecialchars(),輸入端亦可過濾
- 房間隔離:不同房間對應不同文件,邏輯清晰
明顯缺陷與現代重構方向
| 缺陷 | 現代方案 |
| 輪詢刷新(5 秒)資源浪費、延遲高 | WebSocket / Server-Sent Events (SSE) 長連接推送 |
| 文件存儲無索引、無法刪除/編輯、擴展性差 | MySQL/Redis 存儲,支援歷史查詢、撤回、搜索 |
| Frameset 已棄用(HTML5 不推薦),SEO 差、體驗差 | 單頁應用 (SPA) + AJAX / WebSocket |
| 無用戶在線狀態、無私聊、無表情/圖片 | 引入即時通訊框架 |
極簡 WebSocket 版本雛形(Ratchet 庫)
// server.php
$app = new Ratchet\App('localhost', 8080);
$app->route('/chat', new ChatController, ['*']);
$app->run();
// ChatController.php 實現 MessageComponentInterface
// onOpen/onMessage/onClose/onError 四個生命周期方法