2

OK, so here's my second attempt at this, with a new and much more isolated and concise way of demonstrating the problem. The problem pertains to a login system where session vars do not seem to save on the first attempt. But here is the stripped down code that demonstrates the errant behavior:

<?php

session_start();

echo "POST superglobal: <pre>" . print_r($_POST, true) . "</pre><hr/>";
echo "SESSION superglobal: <pre>" . print_r($_SESSION, true) . "</pre><hr/>";
echo "COOKIE superglobal: <pre>" . print_r($_COOKIE, true) . "</pre><hr/>";

$_SESSION['session_var'] = "SESSION VAR AVAILABLE";
setcookie("cookie_var", "COOKIE VAR AVAILABLE");

?>  
<html>
    <body>
        <form action="" name="frmPost" method="POST">
            <input type="submit" name="cmdSubmitPost" value="Submit" />
        </form>
    </body>
</html>

On my localhost on my local computer, here's what this code produces:

After initial page load:

POST superglobal:
Array
(
)

SESSION superglobal:
Array
(
)

COOKIE superglobal:
Array
(
)

[Submit]

After clicking Submit one time:

POST superglobal:
Array
(
    [cmdSubmitPost] => Submit
)

SESSION superglobal:
Array
(
    [session_var] => SESSION VAR AVAILABLE
)

COOKIE superglobal:
Array
(
    [cookie_var] => COOKIE VAR AVAILABLE
    [PHPSESSID] => hpkpft4hh1tqlm6e3r496bt5j2
)

[Submit]

This is exactly what I expect and need. I also signed up temporarily on two separate free php hosting sites to test this, and they both yielded the same results as above.

However, at Arvixe, my main hosting environment, the results are different. There it goes like this:

After initial page load:

POST superglobal:
Array
(
)

SESSION superglobal:
Array
(
)

COOKIE superglobal:
Array
(
)

[Submit]

After clicking Submit one time:

POST superglobal:
Array
(
    [cmdSubmitPost] => Submit
)

SESSION superglobal:
Array
(
)

COOKIE superglobal:
Array
(
)

[Submit]

After clicking Submit a SECOND time:

POST superglobal:
Array
(
    [cmdSubmitPost] => Submit
)

SESSION superglobal:
Array
(
    [session_var] => SESSION VAR AVAILABLE
)

COOKIE superglobal:
Array
(
    [cookie_var] => COOKIE VAR AVAILABLE
    [PHPSESSID] => 2k6ldfl2icdtj1k7sq5dc9qmj3
    [VC-NoCache] => 1
    [_asomcnc] => 1
)

[Submit]

I hope that the results created in the localhost and other temporary free php hosting environments rules out any fundamental flaw in the fairly straightforward code.

OK, so NOW the question: In the Arvixe hosting environment why does the page not recognize the cookie and session values after the first submit? I'm pretty sure that the REAL question is why is the cookie value not recognized after the first submit? (that's the real question because that answers why the session value isn't being recognized... it's because the PHPSESSID cookie isn't yet recognized).

The php.ini values are essentially the same, but if there are particular values that may help to publish here, let me know which ones.

ALSO, I assume that the answer to this question would effectively solve these other three stackoverflow questions:

PHP cookie will not set until the page reloads TWICE. What's going on?

php session variable not stored at first attempt, working fine from second attempt

session variables not set the first time

(none of the solutions there worked for me)

Community
  • 1
  • 1
Bob
  • 31
  • 5
  • 1
    I think you should include the full code instead of the striped down (only relative that is) as this looks like some sort of condition going on some other erroneous logic – DaGhostman Dimitrov Sep 05 '15 at 02:18
  • But the full code is massive. And it is basically a case where I write a hidden field to a form containing a token that is also written to session. Then when the form posts, I compare the two to ensure that the post came from my form (i.e. to prevent CSRF attacks). There it always comes back after the first pass saying "Invalid" (because it doesn't see the session var). The second time it works. Same as here in the stripped down (but fully functional code). Here we can definitely see the failure. – Bob Sep 05 '15 at 02:22
  • And my case presented here kinda rules out erroneous logic since it functions exactly as expected in localhost and two other test php host environments. – Bob Sep 05 '15 at 02:24

3 Answers3

1

Thanks to all for your input. For anyone who may be searching for this answer later, it turns out that the problem was hosting/server-side.

After actually switching hosts (needed for more than just this problem) the same problem followed me to the new host. But on the new host their server settings included something called "varnish caching", which is very different from client-side browser caching. It is server-side cache.

Supposedly it speeds up performance... but if your app relies heavily on real-time cookie and session values that change often, it REALLY messes things up!

I would bet that those other stack overflow posts I linked above in the original post were caused by this.

On the new hosting environment I just turned off all "varnish caching" and everything functioned perfectly. I suspect that the old host had some server-side caching like this.

Bob
  • 31
  • 5
0

I've run into this issue a few times while developing, although I have never used the Arvixe. I am by no means an expert, but this is the research and experience I've had and the two main reasons why beyond coding errors.

Cookies not created immediately on request

Newly created cookies are not immediately available when the page is refreshed. I've had this unexpected behavior before with SESSION_ID and cookies. If for example, you set the cookie in one request, it won't be available until the next request for the server (so the next refresh after you've set the cookie). Accessing $_COOKIE immediately after setcookie()

There can also be weird logic and the way a browser caches web pages, I think that is likely what is going on here.

PHP Session Not Setting - via. www or non-www problem

You said that it occurs on your Arvixe environment and not localhost? You should check if the domain (getting www removed or added) is changing when your click submit. If you do not have correct rules in the htaccess or set via ini_set or other configurations settings in PHP, then you could be getting two session_ids. I can't quite clearly tell from your code, but if that's the case, it would explain why you only get it the second time (since the first submit it loads new domain and set the session variables and cookie variables). Your server may treat www as a new sub-domain and not choose to share the cookie and session_id, but rather create a new one. Try going into Console and executing document.cookie to get information on whether or not it is changing.

Allow php sessions to carry over to subdomains

Extraneous session commands or other reasons

If you have any PHP commands on the page that fiddle with the session_id such as regenerating it or for example:

session_regenerate_id()
session_write_close()

These commands could possibly be affecting your session and causing unexpected behavior. Since it is case-specific, it'd be in your best interest to read further in the documentation on how sessions propagate and are handled. Other than that, it could be cache, browser, headers, placement of session, stale-sessions, previous cookies, and other related issues.

Community
  • 1
  • 1
q.Then
  • 2,743
  • 1
  • 21
  • 31
  • Thanks Valkyrie! Actually, I am almost sure now that the "weird logic and the way a browser caches web pages" is at the root of this, and suspect that the answer lies somewhere in the htaccess file. Unfortunately I know almost nothing about htaccess settings. Supporting the cache theory, it DOES work properly at Arvixe when I append "?nocache=1" to the URL. – Bob Sep 05 '15 at 03:18
0

If the code is exactly the same then the environment is the cause. Do a phpinfo(); for the different hosting environments. Copy the resulting pages and run a diff comparison. This will show you probable inequities in the hosts installations of PHP.

No one is going to be able to troubleshoot the problem with a hosting environment by looking at your code, incomplete or otherwise.

Carl McDade
  • 634
  • 9
  • 14
  • I was just hoping that someone with a lot more PHP experience would look and say, "Oh, yeah, I had that happen... what you can do is add an 'ini_set(xxxxxx);' and that will....." I have compared the phpinfo() output looking for settings that could cause this and nothing jumps out at me (and there are hundreds of lines of output from that, so I'm sure no one would want to see all that). – Bob Sep 05 '15 at 03:21
  • you probably don't want to trust your eyes on this one because it can be something as simple as a cache or session handler. You just want to eliminate any differences in version, installed libraries or server config as the cause. try winmerge or another diff tool. http://winmerge.org/?lang=en – Carl McDade Sep 05 '15 at 10:00
  • Also when you are testing don't use page reload. Always remain consistent and use only a new write into the adressbar. Your posting routine via the form has to be cleared also and page reload does not do this. – Carl McDade Sep 05 '15 at 10:05