Переменные сеанса PHP не переносятся на мою страницу входа в систему, но идентификатор сеанса равен
Вопрос
Я использую PHP 4.3.9, Apache/2.0.52
Я пытаюсь заставить работать систему входа в систему, которая регистрирует значения базы данных в сеансе, где они доступны после входа в систему. Я теряю переменные сеанса, как только меня перенаправляют.
Я использую следующий код для печати идентификатора сеанса / значений на странице моей формы входа в систему и перенаправленной странице:
echo '<font color="red">session id:</font> ' . session_id() . '<br>';
echo '<font color="red">session first name:</font> ' . $_SESSION['first_name'] . '<br>';
echo '<font color="red">session user id:</font> ' . $_SESSION['user_id'] . '<br>';
echo '<font color="red">session user level:</font> ' . $_SESSION['user_level'] . '<br><br>';
Это то, что выводится в моем браузере со страницы входа в систему (я просто закомментирую перенаправление заголовка на страницу входа в систему). Это также правильная информация, поступающая из моей базы данных, так что на данный момент все в порядке.
session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name: elvis
session user id: 2
session user level: 1
Это то, что печатается на моей странице перенаправления / входа в систему (когда я раскомментирую заголовок / перенаправление). Идентификатор сеанса тот же, но я не получаю значений для отдельных переменных сеанса.
session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name:
session user id:
session user level:
Я получаю следующие ошибки:
Неопределенный индекс:имя пользователя
Неопределенный индекс:идентификатор пользователя
Неопределенный индекс:уровень пользователя
У меня есть глобальная header.php файл, который мой loggedIN.php НЕ вызывает, хотя loggedOUT.php вызывает - для запуска сеанса):
header.php
<?php
ob_start();
session_start();
//if NOT on loggedout.php, check for cookie. if exists, they haven't explicity logged out so take user to loggedin.php
if (!strpos($_SERVER['PHP_SELF'], 'loggedout.php')) {
/*if (isset($_COOKIE['access'])) {
header('Location: www.mydomain.com/loggedin.php');
}*/
} else {
//if on loggedout.php delete cookie
//setcookie('access', '', time()-3600);
//destroy session
$_SESSION = array();
session_destroy();
setcookie(session_name(), '', time()-3600);
}
//defines constants and sets up custom error handler
require_once('config.php');
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
some page layout stuff
Login portion is eventually called via include
footer stuff
Мой loggedIN.php ничего не делает, кроме как запускает сеанс
<?php
session_start();
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Тот Самый логика моего скрипта входа в систему, ключевая часть заключается в том, что я извлекаю результаты базы данных прямо в $_SESSION (примерно на полпути вниз).:
if (isset($_POST['login'])) {
//access db
require_once(MYSQL);
//initialize an errors array for non-filled out form fields
$errors = array();
//setup $_POST aliases, clean for db and trim any whitespace
$email = mysql_real_escape_string(trim($_POST['email']), $dbc);
$pass = mysql_real_escape_string(trim($_POST['pass']), $dbc);
if (empty($email)) {
$errors[] = 'Please enter your e-mail address.';
}
if (empty($pass)) {
$errors[] = 'Please enter your password.';
}
//if all fields filled out and everything is OK
if (empty($errors)) {
//check db for a match
$query = "SELECT user_id, first_name, user_level
FROM the rest of my sql here, blah blah blah";
$result = @mysql_query($query, $dbc)
OR trigger_error("Query: $query\n<br />MySQL Error: " . mysql_error($dbc));
if (@mysql_num_rows($result) == 1) { //a match was made, OK to login
//register the retrieved values into $_SESSION
$_SESSION = mysql_fetch_array($result);
mysql_free_result($result);
mysql_close($dbc);
/*
setcookie('access'); //if "remember me" not checked, session cookie, expires when browser closes
//in FF you must close the tab before quitting/relaunching, otherwise cookie persists
//"remember me" checked?
if(isset($_POST['remember'])){ //expire in 1 hour (3600 = 60 seconds * 60 minutes)
setcookie('access', md5(uniqid(rand())), time()+60); //EXPIRES IN ONE MINUTE FOR TESTING
}
*/
echo '<font color="red">cookie:</font> ' . print_r($_COOKIE) . '<br><br>';
echo '<font color="red">session id:</font> ' . session_id() . '<br>';
echo '<font color="red">session first name:</font> ' . $_SESSION['first_name'] . '<br>';
echo '<font color="red">session user id:</font> ' . $_SESSION['user_id'] . '<br>';
echo '<font color="red">session user level:</font> ' . $_SESSION['user_level'] . '<br><br>';
ob_end_clean();
session_write_close();
$url = BASE_URL . 'loggedin_test2.php';
header("Location: $url");
exit();
} else {
//wrong username/password combo
echo '<div id="errors"><span>Either the e-mail address or password entered is incorrect or you have not activated your account. Please try again.</span></div>';
}
//clear $_POST so the form isn't sticky
$_POST = array();
} else {
//report the errors
echo '<div id="errors"><span>The following error(s) occurred:</span>';
echo '<ul>';
foreach($errors as $error) {
echo "<li>$error</li>";
}
echo '</ul></div>';
}
} // end isset($_POST['login'])
если я закомментирую перенаправление заголовка на странице входа в систему, я смогу отобразить переменные $ _SESSION с нужной информацией из базы данных.Однако после перенаправления на страницу входа в систему они исчезают / отменяются.
У кого-нибудь есть какие-нибудь идеи?Я потратил на это почти весь день и не могу сказать, что приблизился к разгадке.
Кстати, недавно я создал 2 простые тестовые страницы, одна запустила сеанс, установила на нем некоторые переменные, отправила форму, которая перенаправлялась на вторую страницу, которая ничего не делала, кроме чтения / вывода переменных сеанса.Кажется, все работает нормально, просто у меня возникли проблемы с тем, что я делаю в своем основном приложении.
Решение
Я не вижу session_start()
в вашем сценарии входа. Если вы не запускаете сеанс, я не думаю, что php сохранит все данные, которые вы поместите в массив $_SESSION
. Также, чтобы быть в безопасности, я бы явно помещал переменные в массив $_SESSION = mysql_fetch_array($result);
вместо того, чтобы просто перезаписывать все с помощью <=>.
Другие советы
Попробуйте сделать
session_regenerate_id(true);
до того, как
session_write_close();
Также.Лучший способ IMO создать скрипт входа в систему - это:
Пусть логика входа обрабатывается на главной странице, к которой пользователь пытается получить доступ.
- Если пользователь не прошел аутентификацию, он возвращается на страницу входа в систему
- Если пользователь аутентифицирован, он получает $_SESSION["auth"] или что-то в этом роде
- Затем, когда пользователь просматривает главную страницу или другие страницы, которым требуется авторизация, он просто проверяет, установлен ли параметр $_SESSION["auth"].
Тогда у вас не возникнет проблем с тем, что сеанс не сохраняется непосредственно перед перенаправлением
... могу ли я добавить к другим ответам, что функция session_start() иногда дает сбой или происходят странные вещи, если ее не поместить в самое первое начало скрипта.В вашем скрипте заголовка попробуйте:
Вместо того, чтобы
<?php
ob_start();
session_start();
Положить
<?php
session_start();
ob_start();
У меня была похожая проблема, когда я обнаружил это:
http://www.w3schools.com/php/php_sessions.asp р>
Вы ДОЛЖНЫ поместить session_start (); до ЛЮБЫХ HTML-тегов