我正在尝试为我的网站创建一个登录页面。我从另一个我建立的站点复制并粘贴了该站点,该站点可以正常运行。我使用echo语句进行了测试,但是尝试登录时得到的只是登录页面的简化版本。它会在将此代码粘贴到HTML代码中的位置处截断。我已经看过它很多次了,双眼交叉,所以我不确定自己缺少什么!非常感谢您的帮助!
<?php
if($_SERVER['REQUEST_METHOD'] != 'POST') {
echo '<form method="post" action=""><p><label for="username">Username:</label><input type="text" name="username" id="username" title="username"></p><p><label for="password">Password:</label><input type="password" name="password" id="password" title="password"></p><p><input type="submit" name="login" id="login" value="Login"></p></form>';
} else {
$username = $_POST['username'];
$password = $_POST['password'];
if($username == "") {
echo '<p>Please enter your username</p>';
} else {
if($password == "") {
echo '<p>Please enter your password</p>';
} else {
$mysqli = new mysqli("localhost","USER","PASSWORD","DB");
if($mysqli->connect_error) {
exit('Error connecting to database');
} else {
$stmt = $mysqli->prepare("SELECT admin_id, admin_username, admin_password FROM admin WHERE admin_username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->bind_result($id, $user, $pass);
while($stmt->fetch()) {
if(password_verify($password, $pass)) {
echo '<p>Logged in</p>';
} else {
echo '<p>Incorrect Password</p>';
}//verify password
} // statements
$stmt->close();
} // connection test
} // check password
} // check username
}
?>
我测试了您的代码,它可以正常工作。没有什么问题。
我建议尽管您说过您仔细检查了数据库,但问题是此PHP代码连接到的数据库中不存在用户名。也许您检查了错误的数据库。
我按原样测试了您的代码,然后对其进行了一些重构。我以为我会告诉你我写这个的方式:
这显示error_log()
的使用,该输出到http错误文件。将技术错误消息输出到可以阅读的地方是一个好习惯,但在浏览器输出中会出现一个更加用户友好的错误。您不想混淆您的用户。
$mysqli = new mysqli("...", "...", "...", "...");
if ($mysqli->connect_error) {
error_log($mysqli->connect_error);
die('Error connecting to database, contact site administrator');
}
将SQL放入变量中,因此,如果有问题,可以将其输出到错误日志中。同样,用户不需要知道技术细节,只需知道它失败了,而网站管理员需要修复它。
$sql = "
SELECT admin_id, admin_username, admin_password
FROM admin
WHERE admin_username = ?";
if (($stmt = $mysqli->prepare($sql)) === false) {
error_log($mysqli->error);
error_log("SQL = [$sql]");
die("Database error, contact site administrator");
}
每个mysqli函数在任何步骤都出现问题时都返回false。您需要检查一下。
if ($stmt->bind_param("s", $username) === false) {
error_log($stmt->error);
die("Database error, contact site administrator");
}
if ($stmt->execute() === false) {
error_log($stmt->error);
die("Database error, contact site administrator");
}
if ($stmt->store_result() === false) {
error_log($stmt->error);
die("Database error, contact site administrator");
}
如果行数为零,则表示用户名不匹配。您想在错误日志中了解此信息,但不要向用户透露。他们应该只知道用户名或密码错误,而不是哪个错误。
if ($stmt->num_rows == 0) {
error_log("Username '$username' not found");
die("Incorrect username or password");
}
if ($stmt->bind_result($id, $user, $pass) === false) {
error_log($stmt->error);
die("Database error, contact site administrator");
}
应该只有与用户名匹配的一行。因此,如果没有匹配的密码,请随时使用die()。
while ($stmt->fetch()) {
if (password_verify($password, $pass) === false) {
error_log("Username '$username' found, but password is wrong");
die("Incorrect username or password");
}
}
$stmt->close();
最后,最后一步:如果我们走到了这一步,那一定是成功的。如果您在每个错误情况下都早于die(),那么您就不必担心深度嵌套的代码块。
echo "<p>Welcome! You are logged in, $username</p>";