You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP循环生成用户列表,Ajax点击仅返回首个用户聊天信息问题

问题描述

我正在开发一款聊天应用,通过PHP while循环生成可用用户列表,点击列表项时,聊天区域应加载对应用户的信息及历史聊天记录(如有)。但目前无论点击哪个用户,Ajax始终仅返回列表中首个用户的信息到聊天区域。尝试过多种从用户列表获取用户ID并通过Ajax传递到active-chat区域的方法,但仍未解决问题,附上相关代码,恳请提供解决方案或改进思路。

原代码

用户列表PHP代码

<?php
// this php is an include in another php file if certain conditions are met.
while($users = mysqli_fetch_assoc($sql)){
    
    // the list of users generated into the home page
    $output .= '<li id="contact" class="get-user-chats">
                    <input type="hidden" id="getUserId" value="'.$users['user_id'].'"/>
                    <span class="avatar"><img src="'.$users['display_pic'].'" height="42" width="42" alt="Generic placeholder image" />
                        <span class="'.$users['online_status'].'"></span>
                    </span>
                    <div class="chat-info flex-grow-1">
                        <h5 class="mb-0">'.$users['full_name'].'</h5>
                        <p class="card-text text-truncate">
                            This is just a test message to see if the truncate feature works
                        </p>
                    </div>
                    <div class="chat-meta text-nowrap">
                        <small class="float-end mb-25 chat-time">4:14 PM</small>
                        <span class="badge bg-danger rounded-pill float-end">3</span>
                    </div>   
                </li>';
                            
}
?>

Ajax代码

$(document).ready(function(){
            $('.users-list').click(function(){
            //users-list is a class from the home page where the users list displays in a div
            var $container = $(this).find(".get-user-chats");
            var chatid = $container.find("#getUserId").val();
            $.ajax({
                url: './code/active-chat.php',
                type: 'POST',
                data: {
                    chatuserid: chatid
                },
                success: function(response){
                    //alert(chatid)
                    $('.get-active-chat-user').html(response);
                },
                dataType: 'text'
                });
            });
        });

active-chat.php代码

<?php 
// active-chat.php
session_start();
define('BASEPATH', true);
require "../../../../private/engine.php";
$chatid = $_POST['chatuserid'];

$sql = "SELECT * FROM users WHERE user_id = '{$chatid}'";
$fetchdata = mysqli_query($connection, $sql);

while($sub = mysqli_fetch_array($fetchdata)){
    ?>
    <header class="chat-header">
        <div class="d-flex align-items-center">
            <div class="sidebar-toggle d-block d-lg-none me-1">
                <i data-feather="menu" class="font-medium-5"></i>
            </div>
            <div class="avatar avatar-border user-profile-toggle m-0 me-1">
                <img src="<?php echo $sub['display_pic']; ?>" alt="avatar" height="36" width="36" />
                <span class="<?php echo $sub['online_status']; ?>"></span>
            </div>
            <h6 class="mb-0"><?php echo $sub['full_name'] ?></h6>
        </div>
        <div class="d-flex align-items-center">
            <i data-feather="phone-call" class="cursor-pointer d-sm-block d-none font-medium-2 me-1"></i>
            <i data-feather="video" class="cursor-pointer d-sm-block d-none font-medium-2 me-1"></i>
            <!-- <i data-feather="search" class="cursor-pointer d-sm-block d-none font-medium-2"></i> -->
            <div class="dropdown">
                <button class="btn-icon btn btn-transparent hide-arrow btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    <i data-feather="more-vertical" id="chat-header-actions" class="font-medium-2"></i>
                </button>
                <div class="dropdown-menu dropdown-menu-end" aria-labelledby="chat-header-actions">
                    <a class="dropdown-item" href="#">View Contact</a>
                    <a class="dropdown-item" href="#">Mute Notifications</a>
                    <a class="dropdown-item" href="#">Block Contact</a>
                    <a class="dropdown-item" href="#">Clear Chat</a>
                    <a class="dropdown-item" href="#">Report</a>
                </div>
            </div>
        </div>
    </header>
<?php } ?>
问题分析与解决方案

核心问题

  1. 重复ID冲突:HTML中ID必须唯一,但循环生成的所有列表项和隐藏输入框都用了相同的id="contact"和id="getUserId",导致JS选择器始终只能获取第一个匹配元素的值。
  2. 事件绑定逻辑错误:原代码将点击事件绑定在父容器.users-list上,通过find(".get-user-chats")只会拿到容器内第一个列表项,因此无论点击哪个用户,传递的都是第一个用户的ID。
  3. SQL注入风险:直接将POST参数拼入SQL语句,存在严重安全漏洞。

修改后的代码

1. 用户列表PHP代码(移除重复ID,改用data属性存储用户ID)

<?php
// this php is an include in another php file if certain conditions are met.
while($users = mysqli_fetch_assoc($sql)){
    
    // the list of users generated into the home page
    $output .= '<li class="get-user-chats" data-user-id="'.$users['user_id'].'">
                    <span class="avatar"><img src="'.$users['display_pic'].'" height="42" width="42" alt="Generic placeholder image" />
                        <span class="'.$users['online_status'].'"></span>
                    </span>
                    <div class="chat-info flex-grow-1">
                        <h5 class="mb-0">'.$users['full_name'].'</h5>
                        <p class="card-text text-truncate">
                            This is just a test message to see if the truncate feature works
                        </p>
                    </div>
                    <div class="chat-meta text-nowrap">
                        <small class="float-end mb-25 chat-time">4:14 PM</small>
                        <span class="badge bg-danger rounded-pill float-end">3</span>
                    </div>   
                </li>';
                            
}
?>

2. Ajax代码(绑定事件到单个列表项,直接从data属性取用户ID)

$(document).ready(function(){
    $('.get-user-chats').click(function(){
        var chatid = $(this).data('user-id');
        $.ajax({
            url: './code/active-chat.php',
            type: 'POST',
            data: {
                chatuserid: chatid
            },
            success: function(response){
                $('.get-active-chat-user').html(response);
            },
            dataType: 'text'
        });
    });
});

3. active-chat.php代码(使用预处理语句防止SQL注入)

<?php 
// active-chat.php
session_start();
define('BASEPATH', true);
require "../../../../private/engine.php";
$chatid = $_POST['chatuserid'];

// 使用预处理语句避免SQL注入
$sql = "SELECT * FROM users WHERE user_id = ?";
$stmt = mysqli_prepare($connection, $sql);
mysqli_stmt_bind_param($stmt, "s", $chatid);
mysqli_stmt_execute($stmt);
$fetchdata = mysqli_stmt_get_result($stmt);

while($sub = mysqli_fetch_array($fetchdata)){
    ?>
    <header class="chat-header">
        <div class="d-flex align-items-center">
            <div class="sidebar-toggle d-block d-lg-none me-1">
                <i data-feather="menu" class="font-medium-5"></i>
            </div>
            <div class="avatar avatar-border user-profile-toggle m-0 me-1">
                <img src="<?php echo $sub['display_pic']; ?>" alt="avatar" height="36" width="36" />
                <span class="<?php echo $sub['online_status']; ?>"></span>
            </div>
            <h6 class="mb-0"><?php echo $sub['full_name'] ?></h6>
        </div>
        <div class="d-flex align-items-center">
            <i data-feather="phone-call" class="cursor-pointer d-sm-block d-none font-medium-2 me-1"></i>
            <i data-feather="video" class="cursor-pointer d-sm-block d-none font-medium-2 me-1"></i>
            <!-- <i data-feather="search" class="cursor-pointer d-sm-block d-none font-medium-2"></i> -->
            <div class="dropdown">
                <button class="btn-icon btn btn-transparent hide-arrow btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    <i data-feather="more-vertical" id="chat-header-actions" class="font-medium-2"></i>
                </button>
                <div class="dropdown-menu dropdown-menu-end" aria-labelledby="chat-header-actions">
                    <a class="dropdown-item" href="#">View Contact</a>
                    <a class="dropdown-item" href="#">Mute Notifications</a>
                    <a class="dropdown-item" href="#">Block Contact</a>
                    <a class="dropdown-item" href="#">Clear Chat</a>
                    <a class="dropdown-item" href="#">Report</a>
                </div>
            </div>
        </div>
    </header>
<?php } ?>

内容的提问来源于stack exchange,提问作者FlilBare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:55:14