首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

聊天室系統(三):訊息輸入框架與表情/私聊功能

     編輯:PHP 綜合知識

功能定位

聊天室底部輸入框架,提供:

  • 訊息內容輸入
  • 接收對象選擇(公開/私聊特定用戶)
  • 動作/表情選擇(說、悄悄、高興、微笑、大笑…共 50+ 選項)
  • 字體顏色選擇
  • 私聊勾選框
  • 修改暱稱彈出視窗連結
  • 離開聊天室連結

資料流向

使用者填寫表單 → 送出到 frame3.php?action=ok
    → 驗證私聊對象是否存在(查 chat_user_list)
    → 寫入 user_message 表
    → 重新導向/重整框架顯示新訊息

完整程式碼

<?php
// frame3.php
require_once "../signup/mysql.php"; // $conn

$userid = $_GET['userid'] ?? $_POST['userid'] ?? '';
$action = $_POST['action'] ?? '';
$p      = isset($_POST['p']) ? 1 : 0; // 是否為送出動作

if ($action === 'ok' && $p) {
    // 1. 取得發送者暱稱
    $stmt = $conn->prepare("SELECT id FROM chat_user_list WHERE userid = ?");
    $stmt->bind_param("s", $userid);
    $stmt->execute();
    $sender_nick = $stmt->get_result()->fetch_row()[0] ?? $userid;
    $stmt->close();

    // 2. 處理接收對象
    $object = $_POST['object'] ?? '大家';
    $private = isset($_POST['private']) ? 1 : 0;
    $target_userid = '大家';

    if ($private && $object !== '大家') {
        // 私聊:將暱稱轉回 userid
        $stmt = $conn->prepare("SELECT userid FROM chat_user_list WHERE id = ?");
        $stmt->bind_param("s", $object);
        $stmt->execute();
        $res = $stmt->get_result();
        if ($row = $res->fetch_assoc()) {
            $target_userid = $row['userid'];
        } else {
            // 找不到該用戶,降級為公開
            $object = '大家';
            $private = 0;
        }
        $stmt->close();
    }

    // 3. 取得下一個 row 序號
    $max_row = $conn->query("SELECT `row` FROM user_message ORDER BY `row` DESC LIMIT 1")->fetch_row()[0] ?? 0;
    $next_row = $max_row + 1;
    $time1 = date("H:i"); // 只存時分

    // 4. 寫入訊息
    $message   = $_POST['message'] ?? '';
    $action1   = $_POST['action1'] ?? '說';
    $color     = $_POST['color'] ?? '#000000';

    $stmt = $conn->prepare("INSERT INTO user_message (userid, object, message, status, action1, color, `row`, time1)
                            VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("sssissis", $userid, $target_userid, $message, $private, $action1, $color, $next_row, $time1);
    $stmt->execute();
    $stmt->close();

    // 5. 修正顯示用 object(私聊時顯示暱稱)
    if ($private && $target_userid !== '大家') {
        $object = $conn->query("SELECT id FROM chat_user_list WHERE userid='$target_userid'")->fetch_row()[0] ?? $object;
    }
}
?>
<!DOCTYPE html>
<html><head>
<meta charset="gb2312"><title>輸入訊息</title>
<script>
function user(nick) {
    // 呼叫父框架 bottom.frame 的 user() 函式,填入私聊對象
    document.form1.object.value = nick;
}
function changnick() {
    window.open("changnick.php?userid=" + encodeURIComponent("<?php echo $userid; ?>"),
                "changnick", "width=340,height=220,status=0");
}
</script>
<style>
body { background:#6699FF; font:12px/1.5 sans-serif; margin:0; }
.layer { position:absolute; }
#formLayer { left:125px; top:4px; width:498px; }
#nickLayer { left:34px; top:6px; font-weight:bold; }
#actionLabel { left:68px; top:47px; }
#changnickLink { left:412px; top:49px; }
#exitLink { left:508px; top:48px; }
#toLabel { left:116px; top:6px; }
#copyright { left:108px; top:82px; width:427px; text-align:center; color:#FF0000; }
select, input { font-size:12px; }
</style>
</head><body>

<div id="formLayer" class="layer">
  <form name="form1" method="POST" action="?action=ok">
    <input type="hidden" name="userid" value="<?php echo htmlspecialchars($userid); ?>">
    <input type="hidden" name="p" value="1">

    <p>
      對:<input name="object" size="10" value="<?php echo htmlspecialchars($object); ?>">
      說:<input name="message" size="30">
      <input type="submit" name="ok" value="發送">
    </p>

    <p>
      動作/表情:
      <select name="action1">
        <option value="說" selected>說話</option>
        <option value="悄悄地">悄悄</option>
        <option value="興高采烈地">高興</option>
        <option value="微微笑著">微笑</option>
        <option value="哈!哈!哈!地笑著">大笑三聲</option>
        <option value="笑嘻嘻">嘻笑</option>
        <option value="奸笑著">奸笑</option>
        <option value="毛手毛腳地">毛手毛腳</option>
        <option value="嘟著嘴">嘟嘴</option>
        <option value="快要哭著">快要哭</option>
        <option value="拳打腳踢地">拳打腳踢</option>
        <option value="不懷好意地">不懷好意</option>
        <option value="遺憾地">遺憾</option>
        <option value="瞪大了眼睛,很訝異地">訝異</option>
        <option value="幸福地">幸福</option>
        <option value="翻箱倒櫃地">翻箱倒櫃</option>
        <option value="悲傷地">悲傷</option>
        <option value="淫淫笑著">淫淫笑</option>
        <option value="流著口水">流口水</option>
        <option value="正氣凜然地">正氣凜然</option>
        <option value="生氣地">生氣</option>
        <option value="大聲地">大聲</option>
        <option value="傻乎乎地">傻乎乎</option>
        <option value="一付很滿足的樣子">很滿足</option>
        <option value="手足無措地">手足無措</option>
        <option value="很無辜地">無辜</option>
        <option value="喃喃自語地">喃喃自語</option>
        <option value="惡狠狠地瞪著眼">瞪眼</option>
        <option value="快要吐地">想吐</option>
        <option value="感到不舒服地">不舒服</option>
        <option value="無精打采地">無精打采</option>
        <option value="依依不捨地">依依不捨</option>
        <option value="吐著白沫地">白沫</option>
        <option value="掩飾不住狂喜的心情">狂喜</option>
        <option value="笑呵呵一拱手">拱手</option>
        <option value="很有禮貌地作了一揖">作揖</option>
        <option value="咳!慨歎萬千">慨歎</option>
        <option value="深深地鞠躬">致歉</option>
        <option value="望著窗外細雨淅淅,不由得雙眼朦朧地">傷感</option>
        <option value="含淚要哭">含淚</option>
        <option value="想到傷心處,淚流如注">大哭</option>
        <option value="抱頭放聲大哭">痛哭</option>
        <option value="好怕怕呀...">害怕</option>
        <option value="感到很是奇特">奇特</option>
        <option value="瞇著小眼睛道">瞇眼</option>
        <option value="咯咯一笑,很大方的">大方</option>
        <option value="臉上泛起了紅暈">臉紅</option>
        <option value="氣憤地嚷道">生氣</option>
        <option value="提高嗓門">大聲</option>
        <option value="運足氣一聲斷喝">斷喝</option>
        <option value="一臉的迷茫">迷茫</option>
        <option value="無奈地聳聳肩">聳肩</option>
        <option value="使勁敲敲自己腦門">拍腦</option>
        <option value="看著別人談笑,無聊的很">無聊</option>
        <option value="顧作沉思狀">沉思</option>
        <option value="一付無辜的樣子">無辜</option>
        <option value="不舒服地">不適</option>
      </select>

      顏色:
      <select name="color">
        <option value="#0000FF">藍</option>
        <option value="#000000">黑</option>
        <option value="#FF0000">紅</option>
        <option value="#FFFF00">黃</option>
        <option value="#800080">紫</option>
        <option value="#008000">綠</option>
        <option value="#00CC00">青</option>
      </select>

      私聊:<input type="checkbox" name="private" value="1">
    </p>
  </form>
</div>

<div id="nickLayer" class="layer"><?php echo htmlspecialchars($sender_nick ?? ''); ?></div>
<div id="actionLabel" class="layer">動作表情</div>
<div id="changnickLink" class="layer"><a href="javascript:changnick()">改名</a></div>
<div id="exitLink" class="layer"><a href="javascript:parent.window.close()">離開聊天室</a></div>
<div id="toLabel" class="layer">對</div>
<div id="copyright" class="layer">2001 @版權所有 <a href="mailto:xiaoyanglg@263.net">FEIT男孩工作室</a></div>

</body></html>

關鍵技術細節

功能實作細節
私聊對象解析前端輸入暱稱 → 後端查 chat_user_list 轉為 userid 存入 DB
公開/私聊切換status 欄位:0=公開, 1=私聊;object 存目標 userid(公開時為「大家」)
動作/表情action1 欄位存中文描述,顯示時組合成「暱稱 對 目標 動作: 內容」
顏色選擇color 欄位存 HEX 色碼,顯示時套用 <font color>
跨框架互動parent.bottom.user('nick') 呼叫底部輸入框架 JS 函式填入私聊對象
彈出視窗window.open() 開啟 changnick.php 修改暱稱
序號產生查詢 MAX(row) + 1,單點寫入無並發問題(低流量可接受)

安全性與改善建議

  • XSS 防護:輸出時使用 htmlspecialchars(),儲存原文。
  • SQL 注入:全程使用 Prepared Statement(範例已採用)。
  • 並發序號衝突:高流量下 MAX(row)+1 會衝突,改用 AUTO_INCREMENT 主鍵。
  • 編碼一致性:資料庫、連線、頁面皆為 gb2312,建議遷移至 UTF-8。
  • 表情系統:建議改為代碼(如 :smile:)前端渲染為 Emoji/圖片,資料庫只存代碼。
  • 私聊權限:顯示端需嚴格檢查 status=1 AND (sender=me OR target=me)。

現代化重構方向

  • 前端:Vue/React 元件化,WebSocket 即時雙向通訊
  • 後端:RESTful API + JWT 驗證,訊息表加 message_type (text/image/file/emoji)
  • 私聊:建立 conversations 表,支援多對多群組聊天
  • 表情:支援 Unicode Emoji、自訂貼圖包、表情建議
  • 訊息撤回/編輯/引用回覆/標記已讀
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved