PHP 会话变量没有传递到我的登录页面,但会话 ID 是
Posted
技术标签:
【中文标题】PHP 会话变量没有传递到我的登录页面,但会话 ID 是【英文标题】:PHP session variables not carrying over to my logged in page, but session ID is 【发布时间】:2010-09-29 17:22:13 【问题描述】:我正在使用 PHP 4.3.9、Apache/2.0.52
我正在尝试让登录系统工作,该系统在会话中注册数据库值,一旦登录就可以使用它们。一旦我被重定向,我就会丢失会话变量。
我正在使用以下代码在我的登录表单页面和重定向页面上打印会话 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>';
这是从我的登录页面打印在我的浏览器中的内容(我只是将标题重定向到登录页面注释掉)。 这也是来自我的数据库的正确信息,所以现在一切都很好。
session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name: elvis
session user id: 2
session user level: 1
这是在我的重定向/登录页面上打印的内容(当我取消注释标题/重定向时)。 会话 ID 相同,但我没有得到各个会话变量的值。
session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name:
session user id:
session user level:
我收到以下错误:
未定义索引:first_name 未定义索引:user_id 未定义索引: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 个简单的测试页面,一个启动了一个会话,在其上设置了一些变量,提交了一个表单,该表单重定向到了第二个页面,该页面除了读取/输出会话变量之外什么也没做。一切似乎都很好,我只是在我的主应用程序中遇到了一些问题。
【问题讨论】:
【参考方案1】:尝试做一个
session_regenerate_id(true);
之前
session_write_close();
还有。 IMO 执行登录脚本的最佳方法是:
让登录逻辑在用户尝试访问的主页中处理。
-
如果用户未通过身份验证,则将其返回登录页面
如果用户通过了身份验证,他会得到一个 $_SESSION["auth"] 或其他东西
然后当用户在浏览主页面或其他需要认证的页面时,他们只需检查是否设置了 $_SESSION["auth"]。
那么你就不会遇到在重定向之前会话不保存的麻烦
【讨论】:
我的登录脚本的逻辑基于***.com/questions/1270005/…【参考方案2】:我在您的登录脚本中没有看到session_start()
。如果您没有开始会话,我认为 php 不会保存您放置在 $_SESSION
数组中的任何数据。另外为了安全起见,我会明确地将变量放入 $_SESSION
数组中,而不是仅仅用 $_SESSION = mysql_fetch_array($result);
覆盖整个内容。
【讨论】:
嘿,将 DB 值手动放入 $_SESSION 数组中看起来很成功。非常感谢!是因为我被 PHP 4.3.9 卡住了吗? @magenta 我猜这是因为执行 $_SESSION = array( ... ) 你不要修改 $_SESSION 对象,而是丢弃引用并用某些东西替换别的。是的,4.3.9 也很古老 :)【参考方案3】:...我可以补充一下其他答案吗,如果没有将 session_start() 放在脚本的最开头,它有时会失败或发生奇怪的事情。在您的标头脚本中,尝试:
代替
<?php
ob_start();
session_start();
放
<?php
session_start();
ob_start();
【讨论】:
【参考方案4】:当我发现这个时,我遇到了类似的问题:
http://www.w3schools.com/php/php_sessions.asp
你必须把 session_start();在任何 html 标签之前
【讨论】:
以上是关于PHP 会话变量没有传递到我的登录页面,但会话 ID 是的主要内容,如果未能解决你的问题,请参考以下文章