PHP - 即使在session_start之后也无法添加会话变量

时间:2014-12-18 21:25:08

标签: php session

大多数关于不添加会话变量的答案已在用户发现会话未启动时结束。

我遇到了一个无法添加会话变量的问题,即使在session_start之后也是如此。

相关代码:

的login.php

<?php 
    require("../common.php"); 
    if(!empty($_SESSION['user'])) { 
        echo "true";
        header("Location: dashboard.php"); 
        die("Redirecting to dashboard.php"); 
    } 
    $submitted_username = ''; 
    if(!empty($_POST)) { 
        $info = " SELECT id, username, password, salt, email, access FROM users WHERE username = :username "; 
        $params = array( ':username' => $_POST['username'] ); 
        try { 
            $stmt = $db->prepare($info); 
            $result = $stmt->execute($params); 
        } catch(PDOException $ex)  { 
            die("Failed to run query"); 
        } 
        $login_ok = false; 
        $row = $stmt->fetch(); 
        if($row) { 
            $check_password = hash('sha256', $_POST['password'] . $row['salt']); 
            for($round = 0; $round < 65536; $round++)  { 
                $check_password = hash('sha256', $check_password . $row['salt']); 
            }  
            if($check_password === $row['password']) { 
                $login_ok = true; 
            } 
        } 
        if($login_ok) { 
            unset($row['salt']); 
            unset($row['password']); 
            $_SESSION['user'] = $row;
            $_SESSION['access'] = "1";
            header("Location: dashboard.php"); 
            session_write_close();
            die("Redirecting to: dashboard.php"); 
        }  else { 
echo "<div id=\"loginfail\" class=\"gradwin\">\n";
echo "  <p class=\"dark1\">LOGIN FAILURE</p>\n";
echo "</div>\n";
            $submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8'); 
        } 
    } 
?> 
<div id="loginbox" class="gradwin">
    <p class="darktitle">HITS Login</p> 
    <form action="index.php" method="post" name="formLogin"> 
    <!-- fake fields for Chrome autofill... -->
    <input style="display:none" type="text" name="fakeusername"/>
    <input style="display:none" type="password" name="fakepassword"/>
        <p class="dark1">Username:</p>
        <input type="text" name="username" autocomplete="off"><br>
        <p class="dark1">Password:</p> 
        <input type="password" name="password" autocomplete="off"><br><br>
        <input type="submit" value="Login" name="loginForm"><br><br>
    </form> 
    <a class="dark" href="register.php">Register</a>
</div>

的common.php

<?php 

    $username = "MYNAME"; 
    $password = "MYPASS"; 
    $host = "localhost"; 
    $dbname = "MYDB"; 
    $conn = new mysqli($host, $username, $password, $dbname);
    $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); 

    try { 
        $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options); 
    } catch(PDOException $ex) { 
        die("Failed to connect to the database: " . $ex->getMessage()); 
    } 
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 
    header('Content-Type: text/html; charset=utf-8'); 
    session_start(); 

我被重定向到dashboard.php页面,所以我知道会话已经启动。 session_start位于common.php文件中。我放了......

echo '<pre>';
var_dump($_SESSION);
echo '</pre>';
在dashboard.php文件中

....我可以看到所有相关的用户数据,但不能看到访问数据。我的阵列回应如下:

array(1) {
  ["user"]=>
  array(3) {
    ["id"]=>
    string(2) "11"
    ["username"]=>
    string(2) "ba"
    ["email"]=>
    string(9) "ba@ba.com"
  }
}

5 个答案:

答案 0 :(得分:2)

在致电session_start()之前发送标头。 session_start()必须在发送任何标头之前发送:

header('Content-Type: text/html; charset=utf-8'); 
session_start(); 

应该是

session_start(); 
header('Content-Type: text/html; charset=utf-8');

或者,更好的是,只需将其移至文件顶部即可。

答案 1 :(得分:1)

尝试在重定向/位置标头之前添加session_write_close()。我注意到在某些情况下,重定向会导致会话无法正确写入。

答案 2 :(得分:1)

IIRC,对die()exit()的来电将停止存储会话数据。其他关闭函数和析构函数将被触发,但不会触发session_write_close()

您需要在session_write_close()之前运行die()或重写该部分以不使用die()

这里有更多信息。 https://bugs.php.net/bug.php?id=49462&edit=1

答案 3 :(得分:0)

你的代码在这里:

if(!empty($_SESSION['user'])) {
    $_SESSION['access'] = "1";
    header("Location: dashboard.php"); 
    die("Redirecting to dashboard.php"); 
} 

我认为错误在于if语句在大括号内运行代码。您已启动代码仅在会话变量&#39; user&#39;不是空的,这完全没问题。但是,您从未为其设置变量,因此代码永远不会设置会话变量&#39; access&#39;存储输入1因此数组正在转储空的会话变量。

试试这个:

<?php 
require("../common.php"); 


    if(empty($_SESSION['user'])) {
        $_SESSION['access'] = "1";
        header("Location: dashboard.php"); 
        die("Redirecting to dashboard.php"); 
    } 

答案 4 :(得分:0)

愚蠢的错误!!!

我在服务器上有两个版本的login.php文件。一个叫做inc_login.php,我正在修改它。 index.php正在看另一个。我把它理顺了,事情很顺利。

其他人有一个不可能的问题,请注意:你可能正在做像我这样愚蠢的事情。