本地与线上主机PHP警告不一致问题排查求助
我知道自己的代码不够规范,但认为此次问题并非由代码质量导致。我实现了根据用户登录/注册表单返回的等级跳转至不同页面的功能,在本地主机运行时无错误,测试正常。但将代码上传至免费主机000webhost(仅修改了数据库连接凭证)后,验证流程出现差异,出现以下警告:
Warning: Undefined array key "level" in /storage/ssd1/382/21909382/public_html/validation.php on line 15 Warning: Undefined array key "admin" in /storage/ssd1/382/21909382/public_html/validation.php on line 27 Warning: Cannot modify header information - headers already sent by (output started at /storage/ssd1/382/21909382/public_html/validation.php:15) in /storage/ssd1/382/21909382/public_html/validation.php on line 28
对应出错代码行:
Line 15: $level = $_POST['level']; Line 27: $_SESSION["admin"]; Line 28: header('location:Admin Page.php');
完整出错文件代码:
<?php session_start(); $con = mysqli_connect('localhost','id21909382_biyo','!Biyo123'); mysqli_select_db($con, 'id21909382_access_levels'); if(isset($_POST['submit'])){ $name = $_POST['user']; $pass = $_POST['password']; $level = $_POST['level']; echo $value ?? ''; $select = " select * from usertable where name = '$name' && password = '$pass'"; $result = mysqli_query($con, $select); if (mysqli_num_rows($result) > 0){ $row = mysqli_fetch_array($result); if($row['level'] == 'admin'){ $_SESSION["admin"]; header('location:Admin Page.php'); }elseif($row['level'] == 'user'){ $_SESSION["user"]; header('location:User Page.php'); } }else{ header('location:index.php'); } } ?>
问题原因及解决办法
Undefined array key "level":线上环境的PHP错误报告等级比本地高,本地可能默认关闭了E_WARNING级别的错误,所以没暴露这个问题。而且你的登录逻辑根本不需要从POST获取
level——用户等级应该从数据库查询结果里取,表单提交的level可以被用户伪造,本身就是安全漏洞。直接删掉$level = $_POST['level'];这行代码即可。Undefined array key "admin":
$_SESSION["admin"];这行只是读取Session键,但你根本没给它赋值,而且这行完全多余。改成$_SESSION["admin"] = $row['name'];(或其他能标识用户的字段)来存储登录状态,就能解决这个报错。Cannot modify header information:前面的警告已经向页面输出了内容,而HTTP头必须在任何页面输出之前发送,所以后续的
header()调用失败。解决前两个问题后,再删掉多余的echo $value ?? '';($value也未定义,同样会触发警告),就能修复这个跳转问题。
本地和线上的核心差异是PHP错误报告级别不同,本地隐藏了警告类错误,线上主机开启了,所以这些代码里的潜在问题在本地没爆发,到线上就全部暴露了。
内容的提问来源于stack exchange,提问作者Phiso

