本文展示聊天室系統入口lt1.php:Session初始化、最大消息ID獲取、用戶在線登記、雙重框架集佈局(消息區+在線列表+輸入區),確立整個聊天室的前端架構基礎。
<?php
session_start();
session_register("chat_hh"); // 當前最大消息ID
session_register("uname"); // 當前用戶名
include("g_fun.php");
f_connectdb();
// 1. 獲取數據庫最大消息ID
$query = "SELECT MAX(lt_id) AS rmaxid FROM lt_t_content";
$res = mysql_query($query, $dbh);
$row = mysql_fetch_array($res);
$f_chat_hh = $row["rmaxid"] ?: 0;
// 2. 計算顯示起始ID(僅顯示最近12條)
if ($f_chat_hh > 12) {
$chat_hh = $f_chat_hh - 12;
} else {
$chat_hh = $f_chat_hh;
}
// 3. 登記用戶在線狀態
$un_len = strlen($name);
$uname = $name;
$query = "SELECT COUNT(*) AS rcount FROM lt_t_online WHERE lt_username = '$name'";
$res = mysql_query($query, $dbh);
$row = mysql_fetch_array($res);
$lcount = $row["rcount"];
if ($lcount == 0) {
// 新用戶插入
$query = "INSERT INTO lt_t_online (lt_username, lt_lasttime) VALUES ('$name', NOW())";
mysql_query($query, $dbh);
}
// 更新最後活躍時間與狀態
$query = "UPDATE lt_t_online SET lt_lasttime = NOW(), lt_state = 0 WHERE lt_username = '$name'";
mysql_query($query, $dbh);
?>
<html>
<head>
<title>PHP無刷新感聊天室</title>
<script>
function wu() {
var un = "<?php echo $name; ?>";
this.f2.document.fyq.username.value = un;
this.f2.document.fyq.username.size = <?php echo $un_len; ?>;
}
</script>
</head>
<frameset cols="*,140" border="1">
<frameset rows="0,*,70,0" border="1" framespacing="0">
<frame src="about:blank" name="tforlt4"> <!-- 頂部佔位 -->
<frame src="about:blank" name="f1" marginheight="3" marginwidth="5"> <!-- 消息顯示區 -->
<frame src="ltsayno.php" name="f2"> <!-- 輸入表單區 -->
<frame src="about:blank" name="bforlt3"> <!-- 隱藏提交目標 -->
</frameset>
<frameset rows="*,150" border="1">
<frame src="ltonline.php" name="f3" marginwidth="0" scrolling="auto"> <!-- 在線列表 -->
<frame src="about:blank" name="f4" marginwidth="0"> <!-- 底部佔位 -->
</frameset>
</frameset>
<noframes><body bgcolor="#FFFFFF"></body></noframes>
</html>
| 框架名 | 來源文件 | 功能 | 尺寸 |
|---|---|---|---|
| f1 | about:blank → JS動態寫入 | 消息顯示區(主視窗) | 剩餘高度 |
| f2 | ltsayno.php | 發言輸入表單 | 70px |
| f3 | ltonline.php | 在線用戶列表 | 150px寬 |
| bforlt3 | about:blank | 表單提交目標(隱藏) | 0px |
| tforlt4/f4 | about:blank | 佔位/預留擴展 | 0px |
// 父頁面向子框架寫入用戶名
function wu() {
this.f2.document.fyq.username.value = "<?php echo $name; ?>";
this.f2.document.fyq.username.size = <?php echo $un_len; ?>;
}
// 消息顯示框架 f1 由 ltsayno.php (f2) 通過 parent.f1.document.write() 動態更新
// 在線列表 f3 由 ltonline.php 定時刷新 (meta refresh 或 JS setInterval)
| 缺陷 | 影響 | 現代方案 |
|---|---|---|
| SEO不可索引 | 搜索引擎無法抓取框架內容 | 單頁應用 (SPA) + 服務端渲染 (SSR) |
| URL不可分享/收藏 | 地址欄始終為入口頁 | History API / Hash 路由 |
| 跨框架通信脆弱 | 同源策略限制、命名易衝突 | 組件狀態管理 |
| 打印/截圖異常 | 僅打印當前聚焦框架 | CSS @media print 控制 |
| 移動端適配極差 | 固定像素尺寸無法響應 | Flexbox/Grid 響應式佈局 |
| HTML5已廢棄 | 現代瀏覽器勸阻使用 | <iframe> 僅用於嵌入第三方內容 |
<div class="chat-app">
<div class="sidebar"><OnlineUsers /></div>
<div class="main">
<MessageList messages={messages} />
<MessageInput onSend={sendMessage} />
</div>
</div>
// 狀態管理
const [messages, setMessages] = useState([]);
const [onlineUsers, setOnlineUsers] = useState([]);
// WebSocket 實時同步
useEffect(() => {
ws.onmessage = e => setMessages(prev => [...prev, JSON.parse(e.data)]);
heartbeat = setInterval(() => ws.send('ping'), 30000);
return () => clearInterval(heartbeat);
}, []);
Frameset曾是實現「類桌面應用」Web佈局的主流方案,但隨著AJAX、WebSocket、前端框架成熟,單頁應用已成標準。理解Frameset有助於維護舊系統,新項目請直接採用現代架構。