表单提交跳转PHP页面后,会话变量$_SESSION['logged']赋值失效问题
问题分析与解决方案
对,就是因为表单提交后浏览器直接跳转到messages.php,当前页面的PHP代码根本不会被执行。当你把表单的action设为messages.php时,用户点击提交按钮后,浏览器会直接向messages.php发送POST请求,当前页面那段处理登录、设置$_SESSION['logged']的PHP代码完全没有运行机会。
你的现有代码逻辑存在问题:第一次加载登录页时,页面会执行$_SESSION['logged']=0等初始化操作,但此时没有POST数据,不会进入登录验证分支;用户提交表单后,请求直接发往messages.php,当前页面的PHP代码不会被再次执行,自然无法设置$_SESSION['logged']=1。
方案一:当前页面处理登录,完成后跳转至messages.php
把表单提交到当前页面(action留空或设为当前页面文件名),处理完登录验证和Session设置后,再通过header()跳转至messages.php。
修改后的代码示例:
<?php session_start(); // 初始化Session $_SESSION['logged'] = 0; $_SESSION['user'] = ''; // 不要存密码到Session,存在安全隐患,直接删除$_SESSION['pswd'] = '';这行 $error_msg = ''; if (isset($_POST['user']) && isset($_POST['pswd'])) { $user = $_POST['user']; $pswd = $_POST['pswd']; $account = new Account(); try { $logged = $account->LogIn($user, $pswd); // 验证通过,设置Session $_SESSION['logged'] = 1; $_SESSION['user'] = $user; // 跳转到messages.php,注意跳转前不能有任何输出 header("Location: messages.php"); exit; // 必须加exit,终止脚本执行,避免后续输出破坏HTTP头 } catch (Exception $e) { $error_msg = $e->getMessage(); } } ?> <!DOCTYPE html> <html> <body class="main"> <?php if (!empty($error_msg)): ?> <p style="color: red; text-align: center;"><?php echo $error_msg; ?></p> <?php endif; ?> <form action="" method="post"> <p><center>Username : <input type="text" name="user" class="form-control"/></center></p> <p><center>Password : <input type="password" name="pswd" class="form-control"/></center></p> <p><center><input type="submit" value="Log in" class="btn btn-primary"/></center></p> </form> </body> </html>
方案二:在messages.php中处理登录逻辑
把当前页面的登录验证代码移到messages.php开头,让表单直接提交到messages.php,在那里完成Session设置。
messages.php示例代码:
<?php session_start(); // 初始化Session $_SESSION['logged'] = 0; $_SESSION['user'] = ''; if (isset($_POST['user']) && isset($_POST['pswd'])) { $user = $_POST['user']; $pswd = $_POST['pswd']; $account = new Account(); try { $logged = $account->LogIn($user, $pswd); $_SESSION['logged'] = 1; $_SESSION['user'] = $user; } catch (Exception $e) { // 验证失败,跳回登录页并提示错误 header("Location: login.php?error=" . urlencode($e->getMessage())); exit; } } // 如果未登录,强制跳回登录页 if ($_SESSION['logged'] != 1) { header("Location: login.php"); exit; } // 下面是messages.php的原有业务逻辑 ?> <!-- messages.php的HTML内容 -->
同时,登录页可保留原表单action,并添加错误提示:
<?php session_start(); $error_msg = ''; if (isset($_GET['error'])) { $error_msg = urldecode($_GET['error']); } ?> <!DOCTYPE html> <html> <body class="main"> <?php if (!empty($error_msg)): ?> <p style="color: red; text-align: center;"><?php echo $error_msg; ?></p> <?php endif; ?> <form action="messages.php" method="post"> <!-- 原有表单内容不变 --> <p><center>Username : <input type="text" name="user" class="form-control"/></center></p> <p><center>Password : <input type="password" name="pswd" class="form-control"/></center></p> <p><center><input type="submit" value="Log in" class="btn btn-primary"/></center></p> </form> </body> </html>
注意事项
- 调用
header("Location: ...")之前,不能有任何HTML输出(包括空格、换行),否则会触发PHP错误;如果必须先输出内容,可以用ob_start()开启输出缓冲。 - 跳转后一定要用
exit或die终止脚本执行,防止后续代码输出内容破坏HTTP头。 - 绝对不要把用户密码存储到
$_SESSION中,这是严重的安全隐患,直接删除$_SESSION['pswd'] = '';这行代码。
内容的提问来源于stack exchange,提问作者modernAlchemist
相关产品推荐
相关产品推荐

