普通网友 2016-07-05 06:50
浏览 59
已采纳

PHP会话的数据在页面重新加载之间不一致 - 但会话ID是相同的

I'm having a really strange problem with some of my PHP code. I have error reporting turned on and nothing's coming up either.

Basically I have a form that pushed data to $_SESSION[]. The code is:

<?php 
session_start();
$_SESSION['contact']['name'] = $_GET['name'];
$_SESSION['contact']['email'] = $_GET['email'];
$_SESSION['contact']['question'] = $_GET['question'];

session_write_close();
header('Location: confirm.php');
exit;
?>

This is working. However, completely at random the confirm.php will or will not recieve this data. If I refresh multiple times I sometimes get the data, sometimes not.

Here's the confirm code:

<?php
ini_set('display_errors', 'on');
error_reporting(-1);

session_start();

print "SeshID:" . session_id() . "<br>";
print "CookieID:" . $_COOKIE['PHPSESSID'] . "<br>";
print "Status" . session_status() . "<br>";
print "Loc" . session_save_path() . "<br>";
print "Cookie";
print_r(session_get_cookie_params());
print "<br>Data:<br>";

print_r($_SESSION);
?>

Again, no errors. Nothing appearing that looks obviously wrong.

The strange thing is that sometimes when I refresh the confirm page I will get an empty "Array ( )". Sometimes I'll get "Array ( [contact] => Array ( [question] => test [name] => [email] => test@test.com) )" for seemingly no reason...

I'm running no other scripts in between doing this - only the script above that checks the content of the session (confirm) need be re-ran and only the data somehow changes. I run the form a few times, then this check script and it's entirely inconsistent. The session and cookie IDs never change and are always the same

Is there some PHP setting I'm missing? It's really weird to me that these are seemingly pulling out old data which has been overwritten.

  • 写回答

2条回答 默认 最新

  • doucuodan0897 2016-07-05 08:17
    关注

    Solved!

    I'll post my own answer for people with the same problem. Thanks to the people who helped in the comments for discovering this for me!

    The Problem

    The problem was that the server was using a cluster or distribution network, mine Azure, to serve the PHP files.

    The first call writes the session data to machine 1, and the confirm is then reading from machine 2, which doesn't have the right info. In clusters, /tmp is often not mirrored, and that is where the session data is stored. Talk to your cluster admin about this. – Bart Friederichs

    It seems like the form was being sent and having the session variables stored on server 1, but the page pulling the session data was server 2, server 3 and sometimes server 1 - hence the odd behaviour of seeing prior submissions and occasionally correct data.

    The Fix

    There are two possible fixes here. One:

    The session store directory isn't being mirrored across all servers

    In this case, change your session directory by changing "session.save_path" in your php.ini or by using

    session_save_path(dirname(__FILE__). '/sessions/');
    

    at the top of the affected files before you call session_start() (this was the ONLY part of our site that uses sessions so this made for a good / dirty fix).

    The point here is to change it to a directory that is for sure being mirrored across every server in your cluster.

    The session is being saved in another way that isn't mirrored

    In my actual case I found that my session handler was the problem. By using

    phpinfo();
    

    I found that my session.save_handler was "wincache", which is a plugin to speed up PHP. One of the ways it appears to do this is by using shared memory or something in order to speed up the loading of the session data.

    Either way, this was not right for my setup and I fixed it by simply changing the variable to use the default: 'files'.

    Again, the best way to do this is by using your php.ini and setting session.save_handler to "files" but I don't have access to that file and so, again, I just used a call in the header of the two files before session_start().

    ini_set("session.save_handler", "files");
    

    I wouldn't recommend this as you know it's going to come up and bite you in the backside later on when a new developer comes in and you forget - it's better to change your .ini

    Anyway, that was that.

    Thanks everyone for your help!

    Aside

    Many server solutions such as Azure actually offer their own plugins and session handlers specifically to counteract this kind of situation. If possible you should of course use them!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程