Я проверил ваш код, и он работает. В этом нет ничего плохого.
Я полагаю, что, несмотря на то, что вы сказали, что дважды проверили базу данных, проблема в том, что в базе данных, к которой подключен этот код PHP, нет имени пользователя. Возможно, вы проверили неверную базу данных.
Я проверил ваш код как есть, а затем немного реорганизовал его Я подумал, что покажу вам, как написать:
Это показывает использование error_log()
, которое выводит в файл ошибок http. Хорошая привычка - выводить сообщение о технической ошибке в месте, где его можно прочитать, но при этом выводить более удобную для пользователя ошибку в выводе браузера. Вы не хотите путать своих пользователей.
$mysqli = new mysqli("localhost","USER","PASSWORD","DB");
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");
}
Должна быть только одна строка, соответствующая имени пользователя. Поэтому, если у него нет подходящего пароля, не стесняйтесь d ie ().
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();
Наконец, последний шаг: если мы дошли до этого уровня, значит, он должен быть успешным. Если вы ранее выполняли d ie () при каждом состоянии ошибки, вам не нужно беспокоиться о глубоко вложенных блоках кода.
echo "<p>Welcome! You are logged in, $username</p>";