PHP登出脚本失效:始终保持登录状态技术求助
你的PHP登录/登出功能问题分析与修复方案
我帮你梳理了代码里的几个关键问题,这些小错误叠加起来导致了现在的异常现象:
1. 会话未初始化
所有使用$_SESSION的页面,必须在任何输出(包括HTML空格、换行)之前调用session_start(),否则会话无法正常工作。你的代码里完全没写这个,这是session值异常的核心原因之一。
2. 数据库连接错误
mysqli_connect($servername,$dbuser,$dbpw,$db,$port)的返回值没有赋值给$con,导致mysqli_query($con,$query)里的$con是未定义的;- 后面的错误处理用了
mysqli_error($connection),但变量名是$con不是$connection,变量名不一致,无法正确输出错误信息排查问题。
3. 登出逻辑被错误嵌套
你把登出的判断if(isset($_POST['logout']))放在了登录提交的if(isset($_POST['send']))代码块里,点击登出按钮时,$_POST['send']不存在,所以这段登出代码根本不会执行,自然无法销毁会话。
4. 登录判断逻辑有问题
- 你没有先检查数据库查询是否返回有效结果,如果用户输入的账号不存在,
$rows = mysqli_fetch_assoc($result)会返回false,此时$_POST['name']==$rows['name']的比较逻辑会出错; - 代码里
$user和$pw变量没有定义,应该从$_POST['name']和$_POST['pw']获取,否则SQL查询里的变量是空的,永远查不到数据。
5. 严重的SQL注入风险
直接把用户输入的$user和$pw拼到SQL语句里,非常容易被注入攻击,必须使用预处理语句来避免这个问题。
修复后的完整代码示例
登录处理部分
<?php // 必须在所有输出之前启动会话 session_start(); // 数据库连接配置(根据你的实际情况修改) $servername = "你的服务器地址"; $dbuser = "数据库用户名"; $dbpw = "数据库密码"; $db = "数据库名"; $port = 3306; // 处理登出请求(单独放在外面,不要嵌套在登录逻辑里) if(isset($_POST['logout'])) { $_SESSION = array(); session_destroy(); // 销毁后跳转到当前页面,避免表单重复提交 header("Location: " . $_SERVER['PHP_SELF']); exit; } // 处理登录请求 if(isset($_POST['send'])) { // 连接数据库并检查连接是否成功 $con = mysqli_connect($servername,$dbuser,$dbpw,$db,$port); if (!$con) { die("数据库连接失败: " . mysqli_connect_error()); } // 获取用户输入并转义(或者用预处理语句更安全) $user = mysqli_real_escape_string($con, $_POST['name']); $pw = mysqli_real_escape_string($con, $_POST['pw']); // 使用预处理语句避免SQL注入 $query = "SELECT * FROM `users` WHERE `name` = ? AND `pw` = ?"; $stmt = mysqli_prepare($con, $query); mysqli_stmt_bind_param($stmt, "ss", $user, $pw); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $rows = mysqli_fetch_assoc($result); // 判断是否查询到有效用户 if($rows) { $_SESSION['logged'] = true; echo "登录成功!"; } else { $_SESSION['logged'] = false; echo "用户名或密码错误!"; } // 关闭数据库连接和语句 mysqli_stmt_close($stmt); mysqli_close($con); } // 初始化session值(避免未定义的情况) if(!isset($_SESSION['logged'])) { $_SESSION['logged'] = false; } ?>
表单部分
<?php if($_SESSION['logged'] == false): ?> <form method="post"> <input type="text" class="form-control" id="name" name="name" placeholder="abc" required> <input type="password" class="form-control" id="pw" name="pw" placeholder="xyz" required> <button type="submit" name="send">Login</button> </form> <?php else: ?> <form method="post"> <button type="submit" id="logout" name="logout">Logout</button> </form> <?php endif; ?>
额外说明
- 密码不要明文存储在数据库里!应该使用
password_hash()加密,验证时用password_verify(),这是安全规范; - 处理完登录/登出后,最好用
header("Location: ...")跳转,避免用户刷新页面重复提交表单; - 可以添加更多的输入验证,比如检查用户名和密码是否为空,避免无效的数据库查询。
内容的提问来源于stack exchange,提问作者Woww
相关产品推荐
相关产品推荐

