PHP 会话变量不会延续到我登录的页面,但会话 ID 是
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/415005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP session variables not carrying over to my logged in page, but session ID is
提问by Rob Booth
I'm using PHP 4.3.9, Apache/2.0.52
我使用的是PHP 4.3.9,Apache/2.0.52
I'm trying to get a login system working that registers DB values in a session where they're available once logged in. I'm losing the session variables once I'm redirected.
我正在尝试使登录系统正常工作,该系统在会话中注册 DB 值,一旦登录它们就可用。一旦我被重定向,我就会丢失会话变量。
I'm using the following code to print the session ID/values on my login form page and the redirected page:
我正在使用以下代码在登录表单页面和重定向页面上打印会话 ID/值:
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>';
This is what's printed in my browser from my login page (I just comment out the header redirect to the logged in page). This is the correct info coming from my DB as well, so all is fine at this point.
这是从我的登录页面在我的浏览器中打印的内容(我只是注释掉重定向到登录页面的标题)。这也是来自我的数据库的正确信息,所以此时一切都很好。
session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name: elvis
session user id: 2
session user level: 1
This is what's printed on my redirected/logged in page (when I uncomment the header/redirect). Session ID is the same, but I get no values for the individual session variables.
这是我重定向/登录页面上打印的内容(当我取消注释标题/重定向时)。会话 ID 是相同的,但我没有得到单个会话变量的值。
session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name:
session user id:
session user level:
I get the following errors:
我收到以下错误:
Undefined index: first_name
Undefined index: user_id
Undefined index: user_level
未定义索引:first_name
未定义索引:user_id
未定义索引:user_level
I have a global header.phpfile which my loggedIN.php does NOT call, though loggedOUT.php does - to toast the session):
我有一个全局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
My loggedIN.phpdoes nothing but start the session
我的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">
The logic of my login script, the key part being I'm fetching the DB results right into $_SESSION (about half way down):
我的登录脚本的逻辑,关键部分是我将数据库结果直接提取到 $_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'])
if I comment out the header redirect on the login page, I can echo out the $_SESSION variables with the right info from the DB. Once redirected to the login page, however, they're gone/unset.
如果我在登录页面上注释掉标题重定向,我可以使用数据库中的正确信息回显 $_SESSION 变量。但是,一旦重定向到登录页面,它们就会消失/未设置。
Anyone have any ideas? I've spent nearly all day on this and can't say I'm any closer to figuring it out.
谁有想法?我几乎花了一整天的时间来解决这个问题,但不能说我离弄明白了。
BTW, I recently made 2 simple test pages, one started a session, set some variables on it, had a form submit which redirected to a second page which did nothing but read/output the session vars. It all seems to work fine, I'm just having issues with something I'm doing in my main app.
顺便说一句,我最近做了 2 个简单的测试页面,一个启动了一个会话,在上面设置了一些变量,有一个表单提交,它重定向到第二个页面,除了读取/输出会话变量之外什么都不做。一切似乎都很好,我只是在我的主应用程序中遇到了一些问题。
回答by Rob Booth
I don't see a session_start()in your login script. If you aren't starting the session I don't think php will save any data you place in the $_SESSIONarray. Also to be safe I'd explicitly place variables into the $_SESSIONarray instead of just overwriting the whole thing with $_SESSION = mysql_fetch_array($result);.
我session_start()在您的登录脚本中没有看到 a 。如果您没有开始会话,我认为 php 不会保存您放置在$_SESSION数组中的任何数据。同样为了安全起见,我会明确地将变量放入$_SESSION数组中,而不是用$_SESSION = mysql_fetch_array($result);.
回答by ólafur Waage
Try doing a
尝试做一个
session_regenerate_id(true);
before the
之前
session_write_close();
Also. The best way IMO to do a login script is this:
还。IMO 执行登录脚本的最佳方式是:
Let the login logic be handled within the mainpage the user is trying to access.
让登录逻辑在用户尝试访问的主页中处理。
- If the user is not authenticated, he is thrown back to the login page
- If the user is authenticated, he gets an $_SESSION["auth"] or something
- Then when the user is browsing the main page or other pages that need auth, they just check if the $_SESSION["auth"] is set.
- 如果用户未通过身份验证,则将其返回登录页面
- 如果用户通过身份验证,他会得到一个 $_SESSION["auth"] 或其他东西
- 然后当用户浏览主页或其他需要身份验证的页面时,他们只需检查是否设置了 $_SESSION["auth"] 。
Then you wont have the trouble of session not saving just before a redirect
那么你就不会在重定向之前遇到会话不保存的麻烦
回答by Aram Alvarez
...may I add to the other answers, that session_start() sometimes fails or weird stuff occurs if not placed at the very first beginning of the script. In your header script, try:
...我可以添加其他答案,如果没有放在脚本的第一个开头, session_start() 有时会失败或发生奇怪的事情。在您的标题脚本中,尝试:
Instead of
代替
<?php
ob_start();
session_start();
Put
放
<?php
session_start();
ob_start();
回答by Dante Jones
I was having a similar problem when I discovered this:
当我发现这个时,我遇到了类似的问题:
http://www.w3schools.com/php/php_sessions.asp
http://www.w3schools.com/php/php_sessions.asp
You HAVE TO put the session_start(); before ANY html tags
你必须把 session_start(); 在任何 html 标签之前

