【问题标题】:Unreliable reading of $_SESSION data$_SESSION 数据读取不可靠
【发布时间】:2017-06-11 00:57:27
【问题描述】:

我在下面抽象了两个 PHP 文件: 文件 1:login.php

<?
ob_start();
session_start();
$q = "SELECT user_id, user_first_name, user_priv, user_reg_date, user_pref, user_last_login FROM Users WHERE (user_email='$e' AND user_pass=SHA1('$p')) AND user_active IS NULL";       
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_num_rows($r) == 1) { // A match was made.

   // Register the values & redirect:
   $_SESSION = mysqli_fetch_array ($r, MYSQLI_ASSOC);
   session_write_close();           
   mysqli_close($dbc);
   $url = BASE_URL . '/CustomIndex.php'; // Define the URL:
   ob_end_clean(); // Delete the buffer.
   header("Location: $url");
   exit(); // Quit the script.
}
?>

文件 2:CustomIndex.php

<?
ob_start();
session_start();
if (empty($_SESSION['user_first_name'])) {
   if(isset($_GET['custom2'])){
      $url = BASE_URL . '/index.php'; // Define the URL.
      ob_end_clean(); // Delete the buffer.
      header("Location: $url");
      exit(); // Quit the script.
   }
   sleep(5);
   $url = BASE_URL . "/CustomIndex.php?custom2=1";
   ob_end_clean(); // Delete the buffer.
   header("Location: $url");
   exit(); // Quit the script.
}

if(isset($_SESSION['user_first_name'])){
//  …program code…
}
?>

当文件 1 (login.php) 被执行时,文件 2 (CustomIndesx.php) 中的“if (empty($_SESSION['user_first_name']))”语句可能有 10% 为真,并且客户端没有被执行,而是被重定向到 index.php,就好像没有设置 $_SESSION 变量一样。

但是,在那之后,如果我直接运行 FILE 2 (CustomIndesx.php),它会读取 $_SESSION 数据并正确执行。

我在“SLEEP”之后添加了所有代码来模拟手动运行 CustomIndesx.php,但除了将重定向延迟 5 秒外,没有任何改变。

谁能提出这种随机行为的原因,以及如何消除它?

【问题讨论】:

  • 顺便说一句,这些脚本在 iPage.com 上运行
  • 你能分享你phpinfo()的会话部分吗?
  • 有人说session.auto_start应该打开。如果您无法更改 php.ini 文件,您可以使用此 ini_set 函数。其他的有点复杂,你可以将会话保存处理程序文件更改为 redis。效率会更高。

标签: php session


【解决方案1】:

1) 重要的是:session_start() 必须是两个页面中的第一行代码。如果没有,则在运行完每个页面脚本后关闭会话。

看看发生了什么

2) 然后,在login.php 代码部分:

session_write_close();           
mysqli_close($dbc);
$url = BASE_URL . '/CustomIndex.php'; // Define the URL:
ob_end_clean(); // Delete the buffer.
header("Location: $url");

您正在与session_write_close() 进行会话并关闭它。然后,在 CustomIndex.php 中,您尝试再次打开它。似乎打开的会话ID不同。因此,尝试删除session_write_close(); 行并再次测试。

祝你好运!

编辑 1:

Login.php:

<?php
session_start();
$q = "SELECT user_id, user_first_name, user_priv, user_reg_date, user_pref, user_last_login FROM Users WHERE (user_email='$e' AND user_pass=SHA1('$p')) AND user_active IS NULL";
$r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_num_rows($r) > 0) {
    $_SESSION = mysqli_fetch_array($r, MYSQLI_ASSOC);
    mysqli_close($dbc);
    $url = BASE_URL . '/CustomIndex.php';
    header("Location: $url");
    exit();
}
?>

CustomIndex.php:

<?php
session_start();

if (!isset($_SESSION['user_first_name']) || empty($_SESSION['user_first_name'])) {
    echo 'SESSION USER_FIRST_NAME IS NOT SET!';
} else {
    echo 'SESSION USER_FIRST_NAME IS OK: ' . $_SESSION['user_first_name'];
}
?>

【讨论】:

  • 我添加了“session_write_close()”试图解决这个问题。所以无论有没有那个代码,我都有同样的问题。
  • @DougStinson 你把 session_start() 放在第一行了吗?
  • @DougStinson 用我的简化答案再试一次。不需要ob_... 函数,也不需要CustomIndex.php 中的重定向,因为您确实需要缩小容易出现“错误”的原因。
  • 我切换了 ob_start() 和 session_start() 的顺序。这可能有所帮助,但由于问题是间歇性的,因此肯定会显示更多测试。谢谢
  • @DougStinson 欢迎您。测试我的 EDIT 1 版本并提供反馈。
猜你喜欢
  • 2022-09-28
  • 2020-10-16
  • 2013-05-24
  • 1970-01-01
  • 2011-12-26
  • 2019-01-20
  • 1970-01-01
  • 2013-08-26
  • 2012-05-01
相关资源
最近更新 更多