Поэтому я недавно создал сценарий входа и раздел для всех моих пользователей, что, очевидно, позволяет им входить в безопасный раздел на веб-сайте для просмотра определенных вещей. Убедившись, что все переменные верны и пользователь ввел правильные данные, я устанавливаю два сеанса. Один сеанс содержит идентификатор пользователя, а другой - время входа в систему.
Затем страница будет перенаправлена на страницу с именем home.php, поэтому у пользователя будет своя собственная маленькая домашняя страница после входа в систему. Однако перенаправление, наконец, работает, но в качестве теста на другой странице все, что я делаю, это запускаю сеанс а затем повторить два сеанса.
Каждый раз они пусты, что означает, что сеансы не переносятся с одной страницы на другую. Понятия не имею, почему, просто не вижу, что пошло не так. Итак, мой вопрос: может ли кто-нибудь увидеть, где я ошибся. Меня проверили, чтобы убедиться, что я использую правильную версию, и мой хостинг ее поддерживает, и все возвращается положительно, поэтому я понятия не имею ... пожалуйста, помогите! :)
<?php
//Session
session_start();
require 'conn.php';
//If the POST var "login" exists (our submit button), then we can
//assume that the user has submitted the login form.
if (isset($_POST['login'])) {
//Retrieve the field values from our login form.
$username = !empty($_POST['username']) ? trim($_POST['username']) : null;
$passwordAttempt = !empty($_POST['password']) ? trim($_POST['password']) : null;
//Retrieve the user account information for the given username.
$sql = "SELECT id, username, password FROM users WHERE username = :username";
$stmt = $pdo->prepare($sql);
//Bind value.
$stmt->bindValue(':username', $username);
//Execute.
$stmt->execute();
//Fetch row.
$user = $stmt->fetch(PDO::FETCH_ASSOC);
//If $row is FALSE.
if ($user === false){
//Could not find a user with that username!
//PS: You might want to handle this error in a more user-friendly manner!
die('Incorrect username / password combination!');
} else {
//User account found. Check to see if the given password matches the
//password hash that we stored in our users table.
//Compare the passwords.
$validPassword = password_verify($passwordAttempt, $user['password']);
//If $validPassword is TRUE, the login has been successful.
if ($validPassword){
//Provide the user with a login session.
$_SESSION["user_id"] = $user['id'];
$_SESSION["logged_in"] = time();
echo " Display Errors: ".ini_set('display_errors', 1);
echo " Display Startup Errors: ".ini_set('display_startup_errors', 1);
echo " Error Reporting: ".error_reporting(E_ALL);
//echo "<script type='text/javascript'>window.top.location='home.php';</script>";
//exit;
//Redirect to our protected page, which we called home.php
?>
<!--<script type = "text/javascript">
alert("Login successful!");
window.location.href = "home.php";
</script>-->
<?php
exit;
} else{
//$validPassword was FALSE. Passwords do not match.
die('Incorrect username / password combination!');
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<!-- Basic Page Needs
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<meta charset = "utf8">
<title>Login</title>
<meta name = "description" content = "Service Department User Registration Details">
<meta name = "author" content = "Ben Smith">
<!-- Mobile Specific Metas
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<meta name = "viewport" content = "width=device-width, initial-scale=1">
<!-- FONT
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<link href = "//fonts.googleapis.com/css?family=Raleway:400,300,600" rel = "stylesheet" type = "text/css">
<!-- CSS
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<link rel = "stylesheet" href = "../css/normalize.css">
<link rel = "stylesheet" href = "../css/skeleton.css">
<!-- Favicon
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<link rel = "icon" type = "image/png" href = "../images/favicon.png">
</head>
<body>
<div class = "container">
<div class = "row">
<h1>Login</h1>
<form method = "post" action = "login.php">
<div class = "row">
<div class = "six columns">
<label for = "username">Username</label>
<input class = "u-full-width" type = "text" name = "username" id = "username">
</div>
<div class = "six columns">
<label for = "password">Password</label>
<input class = "u-full-width" type = "password" id = "password" name = "password">
</div>
</div>
<input class = "button-primary" type = "submit" name = "login" value = "Login"></button>
</form>
</div>
</div>
</body>
Итак, изначально у меня было
//Provide the user with a login session.
$_SESSION['user_id'] = $user['id'];
$_SESSION['logged_in'] = time();
//Redirect to our protected page, which we called home.php
header('Location: home.php');
exit;
и как только он доходит до этой части скрипта, страница просто перезагружается. Поэтому вместо перехода на home.php он обновит login.php, а затем экран будет пустым (очевидно, потому что на экран ничего не выводилось)
Отчет об ошибках Когда я помещаю следующий код в
ini_set('display_errors', 1); ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
Я ничего не получаю в результате
Это классическая проблема с редиректами.
Вам нужно закрыть сеанс перед перенаправлением, чтобы он был сохранен.
session_write_close();
header('Location: home.php');
exit;
Обновить: PHP автоматически сохраняет сеанс в конце скрипта. Но этого не происходит, если сценарий заканчивается на exit
или die
(что часто бывает с перенаправлениями). См. Также этот ответ:
https://stackoverflow.com/a/14870204/358813
обновление 2: См. Также: http://php.net/manual/en/function.session-write-close.php#63970
Я не уверен, что последние версии PHP по-прежнему не сохраняют сеанс при внезапном выходе.
Я не уверен, что это «классическая проблема», мне никогда не приходилось использовать это где-либо, чтобы сохранить сеанс ...
как ни странно, я только что прочитал сообщение Джоэла о системе репутации и сообщение Джеффа о голосовании против и через несколько минут после того, как меня проголосовали против без причины :)
Что касается вашего редактирования: только что протестировано, и это не так, сеанс все еще сохраняется с использованием выхода
Поведение, о котором я говорю, существует уже много лет. Возможно, это изменилось с более новыми версиями PHP, я, откровенно говоря, не знаю.
Удалите первый exit;
, это останавливает дальнейшее выполнение.
Боковое примечание: я разместил это как вики сообщества, так как он был решен в комментариях.
Не приведет ли это к потере данных, которые я храню в своих сеансах?