Experts Round Table Network
Navigate
Home
ArticleWiki
Forum
Journal
Search
Newsletter
Links
Tech News
expertsrt.com
Welcome Guest.
Username:
Password:
Remember me
Forgot your password?
Register
Avoiding a form being sent twice by mistake
Welcome,
Guest
. Please
login
or
register
.
December 01, 2008, 09:02:48 PM
11304
Posts in
1248
Topics by
496
Members
Latest Member:
teentiodo
Home
Help
Search
Login
Register
Experts Round Table Network
|
Serverside Technology
|
PHP
|
Avoiding a form being sent twice by mistake
« previous
next »
Pages:
[
1
]
Print
Author
Topic: Avoiding a form being sent twice by mistake (Read 558 times)
Esopo
Governing Council Member
Offline
Posts: 74
Avoiding a form being sent twice by mistake
«
on:
January 07, 2006, 02:35:55 AM »
The first thread in the PHP TA. What a great honor.
On to the good stuff,
I often use single-page scripts for small needs. For example, a small guestbook page.
When a user adds a post the form is sent to the same page, the information is added to the DB and the page reloaded (by headers) before displaying it to the visitor, so that the post variables are erased to make sure they won't send them twice by mistake (like refreshing the page).
It works very well, but I sense that there must be a different (better) method to achieve the same result.
I heard that something like this may do the trick:
Code:
header("Cache-Control: no-cache, must-revalidate");
But I am not familiar with the way it works.
Logged
nicholassolutions
Administrator
Offline
Posts: 133
Avoiding a form being sent twice by mistake
«
Reply #1 on:
January 11, 2006, 01:31:17 PM »
I suppose you could use sessions:
Code:
//at the top of your script
session_start();
if($_SESSION['processed'] === true) $_POST = array();
//..the rest of your script....
//part where you process the $_POST data
if(!empty($_POST['guestname'])){
//do something with the data....
$_SESSION['processed'] = true;
}
If you're inserting the data in a db, another option is to use some sort of 'checksum.' Add an extra column to your table, checksum, and generate some random code appended to mktime() (on the off chance you generate the same code twice, you're not going to do it at exactly the same time, so this ensures each checksum is unique) that you include as a hidden field in the form. Then, insert this value into the checksum column when you make the database entry. When inserting the data, run a quick check to make sure there is no row where the checksum is equal to the one you have generated (if there is, it's a resubmission of your form), and insert the data accordingly (i.e. don't insert it if the checksum is already there). To make things go more quickly, it might help to only search within a subset of, say, the last 300 records, depending on how big your table is.
Of the two options, I tend to like the session solution from a programmer's point of view. From a practical point of view, the checksum solution might be better, since you don't have to deal with any of the problems you may encounter from using sessions. Even if you're not using a db, you could still use the idea of the checksum to prevent repeated processing, by storing just the checksums one-per-line in a plain old text file that you search when the form is submitted (you might want to clear it every day or so to keep the search from taking too long).
Matt
Logged
Anonymous
Guest
Avoiding a form being sent twice by mistake
«
Reply #2 on:
January 12, 2006, 02:46:26 AM »
A pretty good way of quick way of generating a checksum is to serialize the array of valid columns and then do an md5 on the resultant string.
e.g.
Code:
<?php
function makeValid(array &$am_TestArray, $s_TestElement, $s_TestAs = 'string', $m_TestParameters = NULL)
{
// Invalid data results in an empty string, but the return type will be dependent upon the element's type.
$m_Result = '';
// Does the required element exist within the array?
if( isset( $am_TestArray[$s_TestElement] ) )
{
$m_TestValue = $am_TestArray[$s_TestElement];
switch( $s_TestAs )
{
case 'boolean' : // May be '0', '1', 'on', 'off', 'true', 'false'
if( ( '0' == $m_TestValue ) || ( 0 == strcasecmp( $m_TestValue, 'off') ) || ( 0 == strcasecmp( $m_TestValue, 'false') ) )
{
$m_Result = False;
}
if( ( '1' == $m_TestValue ) || ( 0 == strcasecmp( $m_TestValue, 'on') ) || ( 0 == strcasecmp( $m_TestValue, 'true') ) )
{
$m_Result = True;
}
break;
default :
$m_Result = htmlentities( $m_TestValue );
break;
}
}
return $m_Result;
}
$as_ValidatedPOST = array
(
'Name' => makeValid($_POST, 'Name'),
'Comment' => makeValid($_POST, 'Comment'),
'ReceiveMessage' => makeValid($_POST, 'ReceiveMessage', 'boolean'),
);
$s_Checksum = md5( serialize( $as_ValidatedPOST ) );
echo $s_Checksum;
?>
Logged
VGR
Mentor
Offline
Posts: 682
Avoiding a form being sent twice by mistake
«
Reply #3 on:
January 28, 2006, 07:14:14 AM »
Hi (and hello Richard, it's been a long time ! ;-)
I feel there is no such "better" solution than the one you use (header("Location:") after inserting in DB etc).
As there is no drawback to that solution, and effectively, as you wrote, it works well, I wouldn't even research an other solution.
I would especially NOT rely on headers about the cache-control, they are too unreliable (or if you prefer, a lot of proxies, cache engines, browsers and intermediate devices can simply not honore them, not to say anything about search engines' caches)
about the checksum in the DB, it doesn't simplify your script that much, and it is time consuming for achieving the same result as the one you currently have ;-)
best regards
Logged
techie overlord, answers all kind of questions on
http://www.europeanexperts.org
Esopo
Governing Council Member
Offline
Posts: 74
Avoiding a form being sent twice by mistake
«
Reply #4 on:
January 28, 2006, 08:50:10 AM »
Thanks for your opinions. I was comfortable with my method but had that itch that there might be a better one. Now I feel better, and it is good to see other options that hand't occurred to me.
Logged
Pages:
[
1
]
Print
« previous
next »
Jump to:
Please select a destination:
-----------------------------
ERT 1.5
-----------------------------
=> Round Table Learning Center
=> Bug reports
-----------------------------
Legacy
-----------------------------
=> The next level
=> History of ERT
-----------------------------
Community Affairs
-----------------------------
=> Introductions
=> Ballot Box
===> Closed Polls
=> Soapbox
=> Propose and Consult
===> Propose and Consult...CLOSED
-----------------------------
Bits and Bytes
-----------------------------
=> Tips, Tricks, Snippets, Tidbits And General Pearls Of Wisdom
-----------------------------
Serverside Technology
-----------------------------
=> PHP
=> ASP
-----------------------------
Webservers
-----------------------------
=> Apache
=> IIS
-----------------------------
Databases
-----------------------------
=> MySQL
=> Access
=> MS SQL Server
-----------------------------
Clientside Technology
-----------------------------
=> HTML
=> CSS
=> Javascript
=> Flash
=> WAP/WML
-----------------------------
Web Technologies
-----------------------------
=> General Web Dev
=> Web Standards
=> XML
=> Online Marketing
-----------------------------
Graphics
-----------------------------
=> Graphics Design and Animation
-----------------------------
Programming
-----------------------------
=> .NET
=> JAVA
=> MS DOS Batch Scripting
=> Mathematics
=> C & C++
=> VB
=> Delphi
=> Algorithm design
-----------------------------
Operating Systems
-----------------------------
=> Windows (General)
=> NT Based (2K, 2K-03, NT, XP, Vista)
=> Open Source (All)
-----------------------------
Hardware
-----------------------------
=> Hardware General
=> Gamers Hardware (Advanced)
-----------------------------
Networking
-----------------------------
=> Home (small)
=> Office (large)
=> Internet
-----------------------------
Security
-----------------------------
=> General Security Issues
-----------------------------
Rants/Opinions/Proposals
-----------------------------
=> Site operation
Powered by SMF 1.1 RC2
|
SMF © 2001-2005, Lewis Media
Joomla Bridge by
JoomlaHacks.com