PHP登录代码提取自增id_u时遇未定义索引及Header错误求助
咱们来逐个拆解你遇到的两个问题,帮你彻底搞明白原因和解决办法:
第一个错误:Undefined index: id_u
你这里犯了一个PDO方法使用的小误区:你用了fetchALL(PDO::FETCH_ASSOC),这个方法返回的是所有匹配行组成的二维数组——哪怕数据库里只有1条符合条件的数据,它也是一个包含单个元素的数组,结构大概是这样:
[ ['id_u' => 123, 'username' => 'yourname', ...] ]
所以你直接写$id1 = $result['id_u']肯定找不到这个索引,因为$result是数组的集合,不是单条数据的一维数组。
解决办法很简单,二选一就行:
- 换成
fetch(PDO::FETCH_ASSOC):这个方法只返回第一条匹配的行,是一维数组,直接$id1 = $result['id_u']就能拿到值; - 要是坚持用
fetchALL,就取数组的第一个元素:$id1 = $result[0]['id_u'],不过既然你已经判断了rowCount() == 1,用fetch显然更合理。
第二个错误:Cannot modify header information - headers already sent
这个是PHP里非常常见的问题,核心规则是:header()函数必须在任何输出(包括空格、HTML代码、echo内容)之前调用。你的代码里有两处触发了这个问题:
- 登录失败时,你直接
echo了错误提示,这时候已经向浏览器输出了内容,之后再调用header()跳转就会报错; - 不管登录成功还是失败,你最后都写了
echo "<br>",这个输出会在所有逻辑执行前就被发送给浏览器,哪怕登录成功,这个<br>也会先于header()发送,导致跳转失效。
解决思路是调整逻辑,避免在header()之前输出内容:
- 登录成功跳转后,立刻用
exit或die终止代码执行,不让后续的输出代码运行; - 错误提示不要直接echo,而是存入SESSION,跳回登录页面后再取出显示,这样就不会干扰
header()的执行。
修正后的完整代码
<?php session_start(); include ("dbconnectie.php"); // 已登录则跳转,加上exit避免后续代码执行 if(isset($_SESSION['on'])) { header("location:homepage.php"); exit; } if(isset($_POST['login'])) { $username = $_POST['username']; $password = sha1($_POST['password']); $query = $db->prepare("SELECT * FROM account WHERE username = :user AND password = :pass"); $query->bindParam("user", $username); $query->bindParam("pass", $password); $query->execute(); // 改用fetch获取单条匹配数据 $result = $query->fetch(PDO::FETCH_ASSOC); if($query->rowCount() == 1) { $_SESSION['on'] = $username; $_SESSION['id_u'] = $result['id_u']; header("location:homepage.php"); exit; // 跳转后立即停止代码执行 } else { // 把错误信息存入SESSION $_SESSION['login_error'] = "The username and password do not match"; header("location:signin.php"); exit; } } // 在页面合适的位置显示错误信息 if(isset($_SESSION['login_error'])) { echo $_SESSION['login_error']; unset($_SESSION['login_error']); // 显示后清除,避免刷新页面重复显示 } ?>
最后给你提个小建议:sha1已经是不安全的密码哈希算法了,建议换成PHP官方推荐的password_hash()和password_verify()来处理密码,安全性会高很多。
内容的提问来源于stack exchange,提问作者Arjen
相关产品推荐
相关产品推荐

