PHP会话数据未被存储

时间:2009-07-26 20:20:11

标签: php session

我正在创建一个登录系统,但是当用户登录时,它实际上并不存储我希望它在会话中的任何数据。我甚至检查了会话的文件,它是空的。我有session_start();在所有页面上。还有什么我可能做错了。下面是两个主要页面的代码。

登录代码:

<?
if ($DEBUG == true) {
    error_reporting(E_ALL);
}
require "header.php";

require_once "dbinterface.php";
require_once "user.class.php";
require_once "config.inc.php";

$db = new db($DB['host'], $DB['user'], $DB['pass'], $DB['database']);

$u_result = $db->run("select user_id from users where user_name = '" . $db->escape($_POST['user_name']) . "'");

if ($u_result == false) {
    $url = 'Location: error.php?id=8';
    header($url);
}

if (count($u_result) < 1) {
    $url = 'Location: error.php?id=3';
    header($url);
}

$user = new user($u_result[0]['user_id']);

if ($user->match_password($_POST['pass']) == true) {
    $_SESSION['authenticated'] = true;
    $_SESSION['user_id'] = $u_result[0]['user_id'];
    $_SESSION['user'] = $user;
} else {
    $url = 'Location: error.php?id=4';
    header($url);
}
session_write_close();
header('Location: index.php');

?>

包含在每个页面中的标题:

<?php
if (!session_start()) {
    $url = "Location: error.php?id=13";
    header($url);
}
?>

一点背景:

  • Windows 7(也在Windows上试过
  • server 2008,但目前在7)PHP
  • 5个localy托管问题存在
  • 所有人都存在问题
  • 浏览器

18 个答案:

答案 0 :(得分:11)

以下是一些建议(我真的不知道发生了什么和/或为什么;所以他们只是建议;也许会解决问题^^)

首先,有几个问题:
(至少如果这些建议都不起作用,它们至关重要)

  • 您使用的是哪个版本的PHP / Apache?
  • 你在Windows上吗? Linux?
  • 如果您在“生产”服务器上,您使用的是哪种托管服务?也许它有什么特别之处?
  • 每个人都存在问题?
    • 浏览网站时是否一直存在问题?
    • 当您从其他浏览器访问该网站时,它是否仍然存在?
    • 另一台电脑怎么样?
  • 如果您在脚本末尾使用类似var_dump($_SESSION); die;的内容来设置会话中的数据,它会给出什么?


第一个想法:如果你设置一些标题来禁用浏览器的缓存怎么办?
这样的东西,例如:

session_start();
header("Cache-control: private");


第二个想法(至少如果你在Windows上):你试过禁用你的防病毒/防火墙吗?
会话cookie是否在客户端的浏览器中正确创建?
如果您使用子域(或不使用):cookie的域名是否正常?它的失效日期怎么样?


第三个想法:

  • 您说error_reporting设置为E_ALL,这很不错
  • display_errors怎么样?是否设置为On以显示错误?
  • PHP / Apache的error_log中有什么有趣的东西吗?


另一个问题:你确定在session_start之前绝对没有任何东西可以达到输出吗?甚至不是白色空间?


还有一个:你确定目录/文件的权限吗?

  • 在目录中写入的权限意味着您可以创建新文件和/或删除旧文件。
    • 但是,如果我没记错,那不是你可以修改它们
  • 要修改文件,您还需要对文件进行写访问
    • 实际上,您的网络服务器需要对这些文件的写访问权^^

会话目录以及创建的(空)文件有哪些权限?


我开始没有想法......运气好的话,也许其中一个会是正确的......或者帮助你找出合适的人物!

祝你好运!

答案 1 :(得分:9)

可能的原因是在标题('Location ...')语句之后继续执行。但是看起来你希望它停止,所以你应该添加'exit;'重定向到error.php后。 E.g:

if ($u_result == false) {
    $url = 'Location: error.php?id=8';
    header($url);
    exit;
}

这也可能是您问题的一部分,因为您永远不会转到error.php并查看错误代码。最后一行总是执行:

header('Location: index.php');

由于header()的默认行为是替换现有的标题,所以无论如何都总是转到index.php。

答案 2 :(得分:4)

基于PHP header()文档中的注释,我认为您需要在文件底部执行以下操作。 header('Location: x');是使用header()函数的特殊情况,如果会话在发出header()调用之前没有时间写入,则会干扰会话传递。 session_write_close()应该解决这个问题。

...    
session_write_close();
header('Location: index.php');

答案 3 :(得分:3)

无法找到SessionID。我曾经遇到过这个问题,会话被创造得像疯了一样但没有存储。 (另外,请确保您对会话文件夹具有适当的写入权限,一旦遇到此类问题)

你真正想做的是

$ sessid = session_start(); //用于新会话的开头,

在session_start($ sessid); //在每个后续调用的开始请求中,直到使用session_destroy()

销毁会话

当然,在网页之间传递$ sessid变量取决于你。我更喜欢使用&amp; sessid = link添加剂;&gt; (这样我就会立刻知道什么时候出错了; P)

请记住,确保正确恢复会话的唯一方法是传递会话ID。我知道它是可选的,并且在大多数系统上它应该是开箱即用的,但有时它不会,并且根本不保证共享主机上的会话行为。

就像一个protip一样,尝试用__set()和__get()的'magic'默认处理程序将你的会话包装在一个类中,可能会让你的生活稍微更容易验证会话数据(__call()处理程序是特别是对此有用)。并使该类的构造函数期望一个会话ID,0(或-1或其他)是'开始新会话',并确保如果没有明确设置ID,它会尖叫错误 - 这将提醒您{ {1}}问题。

--------- [编辑

哦,我提到了 - 在一个有很多很多用户请求的共享环境中,没有明确地命名你的会话会导致流血问题(一个用户以另一个用户身份登录)。在大多数情况下,这不会发生,但如果你有一个非常搞砸的托管配置,而不是命名你的会话和依赖'默认行为'可能会导致多次灾难。 ; - )

答案 4 :(得分:2)

远射但值得一提:
PHP是否配置正确以处理会话? 什么是phpinfo()输出?

答案 5 :(得分:1)

  • 首先我建议使用

    使用error_reporting(E_ALL);

    在每个文件的开头

  • 其次,我认为问题在于你包括2个session_starts,以及你可能没有跟踪你想到的同一个session_id。

答案 6 :(得分:1)

我发现当session_start()不是页面上的第一行代码时会弹出奇怪的问题。尝试将您的session_start()移动到您的包含和需求之上,并查看是否修复了它。

答案 7 :(得分:1)

我必须同意杰森早些时候所说的话。只需在登录脚本中的所有内容之前添加session_start();行。将它放在session_start()函数之后的任何地方,甚至不在标题中。

所以像这样修改你的代码

<?
session_start();
if ($DEBUG == true) {
    error_reporting(E_ALL);
}

然后是你的其余代码...

希望这可以解决问题。

答案 8 :(得分:1)

检查您的包含尾随行。 有时候,收盘后的换行?&gt;将输出,并阻止创建会话。在我弄明白之前,这让我很认真。

答案 9 :(得分:1)

我测试了代码,甚至复制了你已经拥有的ini设置。

我制作了一些简单的对象来替换db和user。 而且由于daremon所说的,如果与用户和数据库相关的任何检查失败,它仍将显示一个空的索引页(我的测试索引打印了$ _SESSION超全局的内容)。

那么,错误是否可能在db或user类中?你测试过那些吗? 要查看问题是否存在于这些类中,在daremon之类的每个标头调用之后添加exit是一个简单的问题。

答案 10 :(得分:0)

磁盘空间也可能是问题之一,记得要检查你的磁盘空间,如果它已满,则无法写入。

答案 11 :(得分:0)

确保正确设置了session.save_dir。如果您使用的是Media Temple所在的主页/ #### / domains / html,则可能无法正确设置并且无法保存。

答案 12 :(得分:0)

我遇到了同样的问题。我的解决方案与其他方面有点不同。在我的php.ini文件中,我使用了此设置register_globals=On

在我的代码中,我可以说我有一个$_SESSION['user'],稍后在我的代码中为$user分配了一些内容,它实际上是用我分配给{{{{}}的内容替换了我的$_SESSION['user']信息1}}。

因此,请确保关闭$user或更改变量名称。 = d

答案 13 :(得分:0)

这听起来不像是你问题的原因,但由于你还没有找到解决方案,你也可以检查你的主机是否使用负载均衡而不同步会话数据。这意味着您的用户可以针对每个请求发送到不同的服务器,除非会话数据目录在所有这些服务器上共享,否则会话数据将丢失。

可能不是这里的情况,但它引起了我不久前的严重问题,所以我发布它以防万一。

答案 14 :(得分:0)

访问本网站并下载完成的登录系统(很棒的教程网站!),它和你的一样!

http://net.tutsplus.com/videos/screencasts/how-to-build-a-login-system-for-a-simple-website/

它可能无法回答您的会话问题,但以几乎相同的方式解决主题; D

答案 15 :(得分:0)

首先:您托管的是哪个版本的PHP?

在PHP版本中&lt; 5.3.0 session_start()将始终返回TRUE,即使启动会话失败也是如此。 (参见changelog。)


第二:你试过吗

require_once("header.php");

第三:你应该孤立问题。请尝试以下

  • 创建一个名为session_test.php的新文件,其中包含:

    if( isset($SESSION['garbage']) && !empty($SESSION['garbage']) ) { echo 'Session data: ' . $SESSION['garbage']; } else { $SESSION['garbage'] = 'I like cake'; echo 'Session data written'; }  ?&GT;
  • 在浏览器中转到http://:/session_test.php

  • 如果刷新页面会怎样? (A.k.a:您的会话现在有效吗?)

这将确保问题出在php / apache | IIS组合中,而不是所有其他代码中。

答案 16 :(得分:0)

看看你的php.ini设置。特别是,如果您手动执行session.auto_start,则需要将session_start()设置为0。如果您依赖会话Cookie或透明网址重写,则还需要session.use_cookies=1和/或session.use_trans_sid=1

答案 17 :(得分:0)

看起来没有设置sessionID cookie