0

Edit: I just wasn't exiting after sending the header redirect.

When echoing a session value, inside of an output buffer of an include file, if the value is changed later in the script, the later value is the one echoed.

Our website uses an in house framework wherein each page is in its own file which gets included by index.php. The index file captures the output of the include file in a buffer, and stores it to variable. It does some other things, then echos headers, footers, and the captured include file.

The issue is that the $_SESSION behaves in an unexpected way when following a POST to GET pattern:

Post to a form, it sets something in the session, then do a get redirect to another page. On the redirected page, if you echo something from the session, then manipulate it AFTER the echo statement, the final result is that whatever is echo'd reflects the later change. The same goes for unset; echo something from session, then unset it, and the result is that it echos and empty string.

Here is a basic example:

form.php

if (!empty($_POST['string'])) {
    $_SESSION['message'] = $_POST['string'];
    header("Location: ./index.php?page=formHandler");
    //EDIT - This was not in the original code
    //exit;
} else {
    ?>
    <form action="index.php?page=form" method="post">
        <input type="text" name="string"><input type="submit" />
    </form>
    <?php
}

formHandler.php

if (isset($_SESSION['message'])) {
    echo $_SESSION['message'];
    $_SESSION['message'] = "changed";
}

index.php

session_start();

ob_start();
include $_GET['page'] . ".php";
$page = ob_get_clean();
echo $page;

So, what happens:

Starting at form.php (which is included by index)

Type in a value, post it.

The text "changed" is always displayed, even though it is set after the echo statement.

This is simplified for the sake of example; the header is triggered by rewrites, not get params, and a few other things, but the idea is there.

So my question is what is causing this unexpected behavior, and what can I do to fix it?

Using PHP 5.4

chiliNUT
  • 18,989
  • 14
  • 66
  • 106
  • possible duplicate of [php - Should I call exit() after calling Location: header?](http://stackoverflow.com/questions/3553698/php-should-i-call-exit-after-calling-location-header) – chiliNUT Dec 03 '14 at 15:39

1 Answers1

0

UPDATE: I'm going to go out on a limb and guess that there is a double re-direct somewhere in the code that you haven't shared. This would cause the browser to display 'changed' instead of the entered string as on the second load of the page $_SESSION['message'] will already be set to 'changed'

original answer:

your code as it was was giving me a $_POST['string'] undefined error so I changed

if ($_POST['string']) {

in form.php to

if (isset($_POST['string']) {

and it functions correctly, echoing out the string I enter into the form.

Edit: I have tested without the isset as described above and while I still get the "Undefined index: string" error on index.php?page=form, the page index.php?page=formHandler does echo out the text entered into the form and not 'changed'

Is there maybe something else in code you haven't shared that is causing the problem?

damndaewoo
  • 520
  • 3
  • 11
  • Youre right, it was sloppy not to check if it was set, but thats a warning, not an error, and it still doesnt change anything. It works correctly when its not included and buffered. Did you include and buffer as I described it? – chiliNUT Dec 03 '14 at 00:32
  • I have copy/pasted your code verbatim into three files named the same in their own directory on my dev box and it works just fine (with the warning) – damndaewoo Dec 03 '14 at 00:37
  • php 5.4.16 running on WAMP server. I can try on my production server if you like which is php 5.4.35 running on a debian LAMP stack. Edit: works on production server too – damndaewoo Dec 03 '14 at 00:42
  • The script I pasted wasn't accurate. I wasn't exiting after the header was sent. Does php just run the entire script after the redirect? – chiliNUT Dec 03 '14 at 15:13
  • yes, as far as I'm aware the script will keep processing unless exit() is called. Don't quote me on that though. – damndaewoo Dec 04 '14 at 02:06
  • That is the case. http://stackoverflow.com/questions/3553698/php-should-i-call-exit-after-calling-location-header – chiliNUT Dec 04 '14 at 02:08