使用goto处理输入

The first example is using:

  1. HTTP GET request to load the page.
  2. HTTP POST request submit form.
  3. Form's data is stored in session.
  4. HTTP GET request to load the page.

The second example is using goto to "reflow" the buffer, avoiding the additional HTTP request.

  1. HTTP GET request to load the page.
  2. HTTPPOST request submit form.
  3. Buffer is flushed & content is displayed.

Furthermore, the last example doesn't use sessions.

301

<!DOCTYPE html>
<html>
<head>
    <!-- ow noez! -->
</head>
<body>  
    <?php
    // A very common scenario in user-flow handling is redirecting user to the page itself after submitting form, e.g.

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        if (isset($_POST['a'])) {
            // Suppose there was an error & I've populated the error in $_SESSION.
            // Now I would redirect user back to the form. This is because there
            // is markup in the upper template hierarchy layer, e.g. "<!-- ow noez! -->"

            header('Location: ' . $_SERVER['REQUEST_URI']);

            exit;
        }
    }
    ?>

    <form action="" method="post">
        <?php if (isset($time)):?>
        <pre>This value is from the past: <?=$time?></pre>
        <?php endif;?>
        <pre>Next time: <?php $time = time(); echo $time;?></pre>

        <input type="submit" name="a" value="back in time!">
    </form>
</body>
</html>

goto

<?php
goback:

ob_start();
?>
<!DOCTYPE html>
<html>
<head>
    <!-- ow noez! -->
</head>
<body>  
    <form action="" method="post">
        <?php if (isset($time)):?>
        <pre>This value is from the past: <?=$time?></pre>
        <?php endif;?>
        <pre>Next time: <?php $time = time(); echo $time;?></pre>

        <input type="submit" name="a" value="back in time!">
    </form>

    <?php
    // A very common scenario in user-flow handling is redirecting user to the page itself after submitting form, e.g.

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        if (isset($_POST['a'])) {
            ob_clean();

            $_POST = [];
            $_SERVER['REQUEST_METHOD'] = 'GET';

            goto goback;
        }
    }
    ?>
</body>
</html>

Is the goto scenario not superior to 301?

xkcd
>xkcd

Have you considered using AJAX instead? Then your flow is:

  • HTTP GET to fetch the webpage
  • HTTP POST via AJAX to submit the data
  • Done! Optionally, use JavaScript to update the current view.

Alternatively, you can keep your current code and just move the whole if($_SERVER['REQUEST_METHOD'] === "POST") section to be up where your goto label is. In other words, restructure the program's flow ;)