PHP应用登录表单HTTP错误求助:Azure SQL验证问题排查
我仔细看了你的代码,发现好几个关键问题导致登录功能无法正常运行,甚至引发HTTP错误,咱们一个个来解决:
一、HTML登录表单的问题
- 表单提交方法不匹配:你的
<form>标签没有指定method="POST",默认会用GET方法提交,但你的PHP代码里用的是$_POST来获取数据,这会导致PHP完全拿不到用户名和密码。 - 提交按钮缺少name属性:你的
<input type="submit">没有设置name="submit",所以PHP里的isset($_POST['submit'])永远为false,直接跳回登录页面,根本不会执行验证逻辑。
修正后的login_page.html关键部分:
<form action="verify.php" method="POST"> <!-- 其他内容不变 --> <div class="row"> <input type="submit" name="submit" value="Login"> </div> </form>
二、PHP验证代码的核心问题
1. 语法错误导致HTTP 500错误
你写了$pas = = $_POST['password'];,这里多了一个等号,应该是$pas = $_POST['password'];,这个语法错误会直接导致服务器返回500错误。
2. 变量大小写不匹配
HTML里的输入框name是Username和Password(首字母大写),但PHP里用的是$_POST['username']和$_POST['password'](全小写),PHP的超全局变量是区分大小写的,所以根本拿不到用户输入的值。要统一大小写,比如都改成小写:
HTML里的输入框改成:
<input type="text" name="username" placeholder="Username"> <input type="password" name="password" placeholder="Password">
3. SQL Server不支持LIMIT语法
Azure SQL本质是SQL Server,它不支持MySQL的LIMIT,要改用TOP 1来限制结果行数。
4. sqlsrv_query调用错误
sqlsrv_query的第一个参数必须是数据库连接对象$conn,你漏传了,正确的调用方式是sqlsrv_query($conn, $sql语句)。
5. Session启动位置错误
session_start()必须放在PHP代码的最开头,不能在中间,因为它需要在输出任何HTML内容之前发送session头,否则会出现"headers already sent"的错误。
6. 严重的SQL注入风险
直接把用户输入拼接到SQL语句里是非常危险的,容易被SQL注入攻击,必须改用参数化查询。
7. 密码存储不安全
你直接在数据库里存明文密码,这是非常严重的安全问题,应该用password_hash()加密后存储,验证时用password_verify()。
修正后的verify.php:
<?php session_start(); // 必须放在最开头 if(isset($_POST['submit'])){ $serverName = "xxxx"; $options = array( "UID" => "xxx", "PWD" => "xxxx", "Database" => "xxxx" ); $conn = sqlsrv_connect($serverName, $options); if( $conn === false ) { echo "Could not connect.<br>"; die( print_r( sqlsrv_errors(), true)); } // 获取用户输入,注意大小写统一 $usr = $_POST['username']; $pas = $_POST['password']; // 使用参数化查询防止SQL注入 $sql = "SELECT TOP 1 username, password FROM dbo.users WHERE username = ?"; $params = array($usr); $stmt = sqlsrv_query($conn, $sql, $params); if($stmt === false) { die( print_r( sqlsrv_errors(), true)); } if(sqlsrv_has_rows($stmt)){ $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); // 验证密码(假设数据库里存的是password_hash加密后的密码) if(password_verify($pas, $row['password'])){ $_SESSION['username'] = $row['username']; header("Location: index.html"); exit; } else { // 密码错误跳回登录页 header("Location: login_page.html"); exit; } } else { // 用户名不存在跳回登录页 header("Location: login_page.html"); exit; } sqlsrv_free_stmt($stmt); sqlsrv_close($conn); } else { header("Location: login_page.html"); exit; } ?>
额外提醒
- 赶紧把数据库里的明文密码改成
password_hash()加密后的结果,比如注册用户时用$hashed_pw = password_hash($user_input_pw, PASSWORD_DEFAULT);再存入数据库。 - 开启PHP的错误提示(在开发环境),比如在PHP开头加
error_reporting(E_ALL); ini_set('display_errors', 1);,这样能快速看到代码里的语法错误和警告,方便排查问题。
内容的提问来源于stack exchange,提问作者user3609488

