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 } ?>
问题分析与解决方案
核心问题
- 重复ID冲突:HTML中ID必须唯一,但循环生成的所有列表项和隐藏输入框都用了相同的
id="contact"和id="getUserId",导致JS选择器始终只能获取第一个匹配元素的值。 - 事件绑定逻辑错误:原代码将点击事件绑定在父容器
.users-list上,通过find(".get-user-chats")只会拿到容器内第一个列表项,因此无论点击哪个用户,传递的都是第一个用户的ID。 - 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
相关产品推荐
相关产品推荐

