已经发送标题时,包含的php文件中的session_regenerate_id

时间:2016-02-07 13:50:02

标签: php ajax

我有一个网页,我在其中显示用户的帖子,其中包含另一个从文件夹中获取这些帖子的php文件。我这样做是为了可读性,也因为这包括php文件用于执行ajax调用。在开始时,我正在重新生成一个新会话,但在我所包含的文件中,它还会重新生成一个新会话。

posts_main.php

<?php

include_once '../includes/connect.php';
include_once '../includes/functions.php';

sec_session_start();

if (login_check($mysqli) == false) {
    header("location:../login.php");
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
</head>

<body>
    <div id="posts">
        include('list_posts.php'); ?>
    </div>
</body>

</html>

list_posts.php

<?php

include_once '../includes/connect.php';
include_once '../includes/functions.php';

sec_session_start();

if (login_check($mysqli) == false) {
    header("location:../login.php");
}

//connect to mysql database and echo back results

?>

我的sec_session_start函数如下所示:

function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = false;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();          // Start the PHP session 
    session_regenerate_id(true);    // regenerated the session, delete the old one. 

}

当我启动主帖子页面时,我收到以下错误:

  

警告:session_regenerate_id():无法重新生成会话ID -   已发送的标头   第24行的/Library/WebServer/Documents/includes/functions.php

我意识到这是因为我在发送标题后调用了session_regenerate_id但是出于安全原因我在稍后调用ajax调用中的同一文件时需要在包含文件中使用它。

有什么方法可以解决这个问题并同时保持安全吗?

2 个答案:

答案 0 :(得分:0)

问题是在调用session_regenerate_id()之前发送输出(例如文本或HTML)。

如果您搜索已经发送的&#34;标头,那么Stackoverflow上已经讨论过这个问题的各种解决方案&#34;用PHP。查找在session_regenerate_id()之前发送的输出或仅使用output buffering

确定正在发送的输出的一种简单方法是将session_regenerate_id()替换为echo并查看之前显示的内容。

答案 1 :(得分:0)

您只需删除该行:

session_regenerate_id(true);

或者这样,它将在第一次调用中起作用,而不是在第二次调用中失败:

if (!headers_sent()) {
    session_regenerate_id(true);
}

为什么会在session_start为您创建它时重新生成它?