Sent to me via email recently:
I’ve been looking at the three examples posted in June of 2009 on http://dougv.com/2009/06/retaining-values-in-a-form-following-php-postback-and-clearing-form-values-after-successful-php-form-processing/
None of these nice examples does exactly what I want, and I’m wondering which of them is most easily modified to accomplish what I do want, which is to
(a) display the clean form on some page.
(b) if the user provides entries that do not validate, to display the errors on the same page along with the form (retaining entries provided, awaiting corrections), or
(c) if the user provides entries that do validate, to send the user to a second page, where the (now validated) entries are available, but without re-displaying the form. (This would typically be a “Thank you” page.)
Any thoughts about what might be the best way to accomplish this?
This is the Holy Grail of processing a server post-back form in PHP: Ensuring that once validated and processed, the user cannot resubmit the form.
There are lots of use cases where this makes sense: Taking a credit card payment comes immediately to mind, as does making a reservation or posting a comment / content of some sort.
You request a resource, the HTTP daemon sends a response, and that’s it. No long goodbyes, no phone calls in the morning just to see how you’re doing. It’s over; move on.
A Web server has no long-term memory. Calling the same URL from the same Web browser with the same payload, only a microsecond after a first request, still looks to a Web server like a brand-new thing. Again, because that’s the way it was made to work, and that’s the way it ought to work.
This, however, is not the case with PHP. The same practical reasons that make it desirable for a Web server to forget about you immediately make it really important for PHP to hold on to certain data, even if you don’t need it any more.
Sessions, for example. Or, in this case, the $_POST superglobal.
Superglobals Are Super-Hard To Kill
In layman’s terms, that means you can access $_POST anywhere in a given PHP script: The very first line, the very last line, inside a function, inside an included PHP file, inside a private final class member … everywhere and anywhere. Which is pretty awesome, except for when it’s not. Like, when you are trying to get PHP to dispose of that variable.
In short, PHP uses what is effectively a special kind of session to hold on to superglobals. Yes, that’s correct: Even if you haven’t explicitly instructed PHP to establish a session, any time you make a request that involves the creation or populating a superglobal, PHP makes its own, not-directly-accessible-by-code kind of session, to hold on to that superglobal.
Because this “session” is automagic, and because we cannot access it directly by code, destroying it is tricky.
In theory, we should be able to call unset on $_POST; the docs tell us that unset “destroys the specified variables.”
Oh, but then we scroll down, and scroll down some more, and some more. And we see that there are all sorts of caveats and conditions and context under which unset works; that the more complicated the scope of a variable proves, the less predictable unset proves.
And we are dealing with a superglobal: A variable intended to be omnipresent, and therefore necessarily hardy.
To get rid of a superglobal, we actually need PHP to jettison that special session it created. And the only effective way to do that is — just as with a basic Web server — create a whole new request.
But keep in mind, we’re talking about a fully developed, exceptionally extensible technology stack here. Which means that there are also workarounds we can employ; techniques or tricks that don’t force a new request / superglobals session, but which have the same net effect.
It’s that option we’ll discuss in Part 3 of this series. But first, Part 2: Server-side form validation.