【问题标题】:Php Session forgotten from one script to another从一个脚本到另一个脚本忘记了 PHP 会话
【发布时间】:2017-05-31 04:41:24
【问题描述】:

我目前正面临 php 会话的问题。我一直在到处寻找答案,但我担心我的问题太具体了......

问题如下:我正在构建一个仅显示一页 index.html 的网站。此页面包含一个 div #container,每次我通过 route() 函数在工具栏中选择一个选项卡时,它的内容都会被替换。它可以工作this way:

一旦 Mustache 渲染了 json 数组 «articles»,templates.html 页面包含所有要替换到页面中的信息。 这里是对应的#tpl-articles(我把不需要的部分删掉了)

现在,有一个«登录»选项卡,它将信息发送到«connexion.php»脚本。此脚本设置 $_SESSION['user_id'] 和 $_SESSION['user_surname']。我的问题是:如果我转到另一个选项卡 - 说“默认”选项卡(在同一个 index.html 页面上) - 我的 load_articles.php 不再知道上述 $_SESSION 变量:/

这是«connexion.php»代码:

<?php

header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jul 1980 05:00:00 GMT');
header('Content-type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin:*');

session_name('MODAL'); 
session_start();

ini_set('session.use_cookies', 0);
ini_set('session.use_only_cookies', 0);
ini_set('session.use_trans_sid', 1);

$msgJson = array();

$msg = array('session_id' => session_id());
array_push($msgJson, $msg);

// info from the «log in» tab
$email = strip_tags($_POST['email']);
$password = strip_tags($_POST['password']);


require('database.php');
$dbh = Database::connect();

$query  = "SELECT * FROM `users` WHERE `email`=? AND `password`=?";

$sth = $dbh->prepare($query);
$sth->execute(array($email,sha1($password)));

$tab = $sth->fetchAll(PDO::FETCH_ASSOC);

if (count($tab) == 1) {
    $_SESSION['user-id'] = $email;
    $_SESSION['user_surname'] = $tab[0][surname];
    $msg = array('success' => $_SESSION['user_surname']);
} 
else {
    $msg = array('error' => 'Fail');
}

array_push($msgJson, $msg);
echo json_encode($msgJson);
?>

这里是 load_articles.php,它不知道 $_SESSION 变量:

<?php

header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jul 1980 05:00:00 GMT');
header('Content-type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin:*'); 

session_name('MODAL');
session_start();

require 'database.php';
$dbh = Database::connect();

if ( !isset($_SESSION['user-id’])){
    $query = 'something';
    $sth = $dbh->prepare($query);
    $sth->execute();
    $result = $sth->fetchAll(PDO::FETCH_ASSOC); 
}

else {
    $query = 'something_else';
    $sth = $dbh->prepare($query);
    $sth->execute(array(
            $_SESSION['user-id'],
            $_SESSION['user-id']
            ));
    $result = $sth->fetchAll(PDO::FETCH_ASSOC);
}

echo json_encode($result);
?>

有人会理解为什么这些会话变量似乎消失了吗? 我究竟做错了什么 ? index.html 页面是否应该首先从指定 session_start() 的 php 代码生成?这对我来说是个大问题……

提前感谢您的帮助和耐心,我是初学者:/

【问题讨论】:

  • 警告:编写自己的访问控制层并不容易,而且有很多机会会严重错误。当任何现代的development frameworkLaravel 带有强大的authentication system 内置时,请不要编写自己的身份验证系统。至少遵循 recommended security best practices 并且永远不要使用 SHA1 或 MD5 等无用的弱哈希存储密码
  • 第二段代码中有一个“智能引用”。希望您使用的代码编辑器不会因设计而损坏。
  • &lt;?php @session_start()之后移动session_start
  • @num8er @ 认真的吗?你需要处理错误而不是隐藏它们
  • @tadman 谢谢你告诉我!不幸的是,这只是我在复制代码块时犯的一个错误:/

标签: php html session


【解决方案1】:

您的session 函数应放在页面的第一行。 因此,将session_start() 和会话功能放在页面顶部,例如超过所有其他 header 代码。

请参阅thisthisthis 答案。

祝你好运。

【讨论】:

    【解决方案2】:

    问题出在这里:

    header('Cache-Control: no-cache, must-revalidate');
    header('Expires: Mon, 01 Jul 1980 05:00:00 GMT');
    header('Content-type: application/json; charset=utf-8');
    

    只需删除它们。

    PHP 代码没有缓存在浏览器上,担心告诉浏览器它必须自动过期



    奖金:

    试试这个代码

    <?php
    
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
    
    session_start();
    header('Access-Control-Allow-Origin:*'); 
    
    require 'database.php';
    $dbh = Database::connect();
    
    function responseJSON($data, $exit = true) {
      header('Content-type: application/json');
      echo json_encode($data);
      if($exit) exit(0);
    }  
    
    $userId = isset($_SESSION['user-id']) ? $_SESSION['user-id'] : null;
    
    if($userId) {
       $query = 'something_else';
       $sth = $dbh->prepare($query);
       $sth->execute([$userId, $userId]);
       responseJSON($sth->fetchAll(PDO::FETCH_ASSOC));
    }
    
    
    $query = 'something';
    $sth = $dbh->prepare($query);
    $sth->execute();
    responseJSON($sth->fetchAll(PDO::FETCH_ASSOC));
    

    【讨论】:

    • 非常感谢@num8er!我删除了所有这些标题,但删除了“内容类型”一个,没有它我的页面不理解 php 发回的内容......我尝试了没有标题的代码('Access-Control-Allow-Origin:*')但我收到错误消息:“XMLHttpRequest 无法加载 localhost:8888/uptimo/load_articles.php。Access-Control-Allow-Origin 不允许来源 localhost:63342。” ...
    • ... 所以我写了一个 .htaccess 文件,规定“ Header set Access-Control-Allow-Origin * Header set Access-Control-Allow-Credentials true " 但这并不能解决我的问题:/
    • 会话开始后如何添加cors header?
    猜你喜欢
    • 1970-01-01
    • 2013-10-02
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多