Do not refresh php page - php

On my page, after the user has submitted a code, the script makes a new record in the database. If after he has submitted the code the user hits refresh, it will make a duplicate record in the database. If he hits refresh 10 times, it will make 10 records with the same data...
Is there some way I can make the page not to refresh for the second time?? Or to limit the number of refreshes the page can get? What solutions can be applied to avoid this situation?
Thank you in advance.

Before adding the record into the data table, use select query to check the data is alreary exists or not in the data table and redirect the page to a new page, say thank you or confirmation of insertion.
Select id from TABLE where data='".$_POST["data"]."';
....
....
if(empty($rs["id"])){
// insert the data in table;
}else{
// do edit or skip to redirect
}
and Rediret
header("location:thankyou.php");
exit();

After the records are saved in the database, use header() and redirect to the same page.
Check the answer to this question, maybe you can use the same code.

It sounds like the PHP script that produces the form is the same one that processes it. You may want to consider setting up a separate PHP script to handle the form. For example:
<form action="action_handler.php" method="post">
Then, at the end of action_handler.php, you would redirect to the original page as follows:
header('Location: original_page.php');

Simple one is unset($_POST["data"]) after inserting it to database or try header('location:.')

When dealing with POST-data you should always employ a POST/REDIRECT/GET setup (Wikipedia. This way, when a user refreshes the destination page, nothing really happens besides a refresh.
The best way for a redirect method is to use status code 303 (HTTP Status Codes), which tells the browser that the POST-data has been received, processed and that the user should go to a new page for the 'response'. When a user hits 'back' he or she should get a message that the page is no longer available or valid (this disabling rePOSTing via that route).
You can use this example to redirect to another page (fairly generic example, but I have baseline code I could use):
header("HTTP/1.1 303 See Other");
header("Location: http://www.yourdomain.com/desitnation.php");

Related

PHP - return the same page with changes

I have html page where you can insert some information and then submit this form, which will change information in database. I do it normally, that submit button call php file in server.
But what I want, is that this php file will return to me the same html page of which I sent request, with modified changes. e.g: there will be "Database update successfully" text added etc.
How can I do it without AJAX ?
Thanks
In the PHP file, do a call to the header() function to redirect the user. For example:
header('Location: url.php');
To change the content of that page they are redirected to, you could pass something in the URL that your page will check for. For example:
header('Location: url.php?submitted=1');
There are other ways to implement this, but this seems the most straightforward to me. Note that you don't want to call header() until the end of your submission page.
Use POST/REDIRECT/GET
Excerpt:
The user submits the form
This is pretty straight forward. The user completes the form and submits it by pressing the submit button or enter on their keyboard.
We store the form data in a session
After processing the data we discover an error so we need to redisplay the form with an error message but we also want to populate
it with their data so they don't have to refill the entire form just
to fix potentially one little mistake. So we store their data in a
session ($_SESSION). Session variables carry over from page-to-page
for as long as the session is valid or until they are deleted. This is
an ideal place to put their information since redirecting will cause
their information to be immediately discarded by the server.
We redirect the user back to the same page using a 303 redirect
Once we have saved the user's information in their session we need to redirect them back to the same page. In order for this to work
properly we need to use a 303 redirect. This means we need to send a
303 header with our redirect. A 303 redirect will cause the browser to
reload the page without the initial HTTP POST request to be
resubmitted. This includes when the user uses the back or refresh
buttons.
We re-populate the form using the data stored in the session
When the page is sent to the user we re-populate it with their information we saved in their session.
Only by generating the whole page in CGI first, unless you go through some horribly convoluted method of getting value of one of the fields to be set to document.innerHTML or something like that in Javascript. But you'll go through hell to get the quoting issues resolved. Use AJAX, it was created for precisely this purpose and exactly to avoid the utter hell associated with what you need.
Alternatively: the "modified piece" of the page may be an iframe, and you can set the target attribute of the form, so that the PHP returns only the iframe content.

Avoid resending forms on php pages

Is there a way to avoid reprocessing forms when I refresh php pages? I'd like to prevent resending forms when refreshing links to php files with an insert function in them. For example, I am processing a series of notes written by users at the top of each page for a new note. Besides the obvious creating a separate php file with a header function is there another way to do it?
Use the Post-Redirect-Get Pattern.
Accept a Post request
Process the data
Issue a redirect response
Accept a Get request
Issue a 200 response
If you need to display data from the submitted stuff, then include a row id or similar in (for example) the query string of the URL you redirect to.
The best way would be to do a header("location: form.php"); call after you process the form. That would redirect you back to the form page, and if you refresh, the browser wont resend the form data.
Alternatively, you could check to see if you already processed the data received, but that would still give you the browser warning message that you are going to resend the data.
You might do both, just in case someone uses the back button and accidentally clicks Submit again.
Just set some flag when you process the form first time so you could check for it and abort reprocessing later on. Session variable or cookie will work fine.
You could put a nonce into the page that is only allowed to be used once so that if you see the same nonce come in you don't do the insert of the page.
I redirect users to a new page after processing of the form.
The form is a POST-request to do-something.php. I check the input data and if it validates I process the data and perform a redirect to do-something.php?somethingdone. So the user can hit F5 w/o resending the POST request.
I tried to use header("Location:..."), $_POST = array(), unset($_POST), but (idk why) they didn't work in my php page.
So, what I did, I just used
echo '< script>window.location.replace("http://.../this.php")</script>'
😂 it works very good! Maybe it is not a good idea, I am learning PHP for the 4th week.

PHP clear browser cache to avoid form data resend after refresh

I'm developing a PHP-MySQL app that enables registered users to enter text comments. Problem is:
User sign-in into the web site - OKAY
User presented with a form to submit text comment - OKAY
User enters text comment and submits - OKAY
I have a routine that sanitize the comment & save it into MySQL (with userid, textcomment, datetime stamp) & present back the user that his/her comment is entered - OKAY
User decides to refresh browser - a duplicate comment is entered - BAD!
I was thinking 3 options:
OPTION 1: Routine that checks: last time user posted comment, and if so, check if this is a duplicate. If duplicate then display error message.
OPTION 2: Routine that does not allow a user to post too quickly. So basically do not allow postings of comments within 1 minute or so. So if browser is refreshed the comment will be ignored.
OPTION 3: Manipulate the browser cache to clear out its contents so when refreshed no duplicate will be entered.
Now in the context of my application, my concerns with OPTION 1 and OPTION 2 is performance PHP-MySQL since I already have various queries within the same page that push/get data from databases. So OPTION 3 may target the issue differently.
Questions is: If I go for OPTION 3 can this be considered a Best Practice? meaning clearing the browser cache is the best most effective solution? I have read that there are consequences too? your thoughts are appreciated!
Just do a redirect after submitting data to the database. It's a common practise.
An http redirect instructs the browser to issue an http GET for the url specified (as opposed to the http POST that is used to submit the form) . If you do this right after you have inserted data into the database, when the user refreshes his browser nothing will happen other than him seeing the same page again.
This question on SO tells how you redirect with php.
Just unset the posted variable after you have inserted it in the database
<?php
if(isset($_POST["comment"])){
//store in the database
//on successful storage
unset($_POST["comment"]);
}
?>
Thus the value won't be posted back when user refreshes the page...
You need to implement the Post/Redirect/Get pattern.
I would use Option 4: Use a one-time form token that authenticates the form request. If the request was successful, invalidate the token.
When doing this, even returning to the form after a redirection won’t allow it to send the form again. Additionally, this will also make CSRF attacks harder.
After entering data into database redirect the page using header or location.href
i have found new way try this.
function PreventResendData($invalidpage='index.php'){
if( $_POST && !is_array( $_SESSION['post_var'] ) ) {
$_SESSION['post_var'] = $_POST;
header('location:'.$_SERVER['PHP_SELF']);
}
else if($_SESSION['post_var'])
{
$_POST = $_SESSION['post_var'];
$_SESSION['post_var'] = '';
}
else
{
header("location:".$invalidpage);
}
}

Does this protect me against page reload and the back button?

Further to my previous question, here's what I decided to implement; it may not be pure P-R-G, but it seems ok. Care to comment?
The form.php has an action; let's call it validate.php.
validate.php is never seen by the user; if validates all $_GET and, if valid writes it to database and generates the HTML of a confirmation page / if not valid, it generates the HTML of an error page explaining what is wrong.
Whichever HTML is generated get stored in a $_SESSION variable and then validate.php does a header('Location: <as appropriate>);
Finally a page called submitted.php of invalid_input.php (in case the user reads the URL) consists only of echo $_SESSION['form_html'];
That seems to me like is proff against both page reload and back button problems.
Or did I goof by trying to reinvent the wheel?
Firstly, you're better off storing the form data, which means you can perform the validation again. It will also be less html. The problem with the method you're employing now is that it doesn't protect against multiple tabs, since $_SESSION is universal to a browser session.
One way I've used to prevent against duplicate submission (without PRG) is to generate a unique id for every page load (where a form is involved). When I generate that unique id, I add it to a $_SESSION['form_unique_ids'] array, and I include it as a hidden field in every form I generate. Then before I take action on a form submission, I check to see if that unique id is in the session. If it is, this is the first time that form has been submitted, and I remove it from the session. That way if I try to resubmit that page, I will know because that id is not in the session not to process the results.
This could be extended so that instead of storing a single id, you use the id as the key in the array, and let the value be the result of the transaction. Then:
If there are errors, you store the $_POST data as well. Then, redirect to original_form.php?id=unique_id and display the validation results. You can either store them or recalculate them there.
If there is success, store the success message and redirect to success_page.php?id=unique_id. Display the success message prominently there. If you like, you can remove it from the page.
You have the option of removing the session data when you display it, but that would mean if they refreshed the edit page they'd lose the validation messages and saved form data. I'd rather find a way to get rid of data that is old enough that they're not likely to need it anymore.
Anyway, some of those ideas might be useful. Then again, maybe it's way too much effort for the problem. Your call :)
As long as you use a php redirect at the end of your validate you cannot reload or back button into the validate.php

Prevent Back button from showing POST confirmation alert

I have an application that supplies long list of parameters to a web page, so I have to use POST instead of GET. The problem is that when page gets displayed and user clicks the Back button, Firefox shows up a warning:
To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier.
Since application is built in such way that going Back is a quite common operation, this is really annoying to end users.
Basically, I would like to do it the way this page does:
http://www.pikanya.net/testcache/
Enter something, submit, and click Back button. No warning, it just goes back.
Googling I found out that this might be a bug in Firefox 3, but I'd like to somehow get this behavior even after they "fix" it.
I guess it could be doable with some HTTP headers, but which exactly?
See my golden rule of web programming here:
Stop data inserting into a database twice
It says: “Never ever respond with a body to a POST-request. Always do the work, and then respond with a Location: header to redirect to the updated page so that browser requests it with GET”
If browser ever asks user about re-POST, your web app is broken. User should not ever see this question.
One way round it is to redirect the POST to a page which redirects to a GET - see Post/Redirect/Get on wikipedia.
Say your POST is 4K of form data. Presumably your server does something with that data rather than just displaying it once and throwing it away, such as saving it in a database. Keep doing that, or if it's a huge search form create a temporary copy of it in a database that gets purged after a few days or on a LRU basis when a space limit is used. Now create a representation of the data which can be accessed using GET. If it's temporary, generate an ID for it and use that as the URL; if it's a permanent set of data it probably has an ID or something that can be used for the URL. At the worst case, an algorithm like tiny url uses can collapse a big URL to a much smaller one. Redirect the POST to GET the representation of the data.
As a historical note, this technique was established practice in 1995.
One way to avoid that warning/behavior is to do the POST via AJAX, then send the user to another page (or not) separately.
I have been using the Session variable to help in this situation. Here's the method I use that has been working great for me for years:
//If there's something in the POST, move it to the session and then redirect right back to where we are
if ($_POST) {
$_SESSION['POST']=$_POST;
redirect($_SERVER["REQUEST_URI"]);
}
//If there's something in the SESSION POST, move it back to the POST and clear the SESSION POST
if ($_SESSION['POST']) {
$_POST=$_SESSION['POST'];
unset($_SESSION['POST']);
}
Technically you don't even need to put it back into a variable called $_POST. But it helps me in keeping track of what data has come from where.
I have an application that supplies long list of parameters to a web page, so I have to use POST instead of GET. The problem is that when page gets displayed and user clicks the Back button, Firefox shows up a warning:
Your reasoning is wrong. If the request is without side effects, it should be GET. If it has side effects, it should be POST. The choice should not be based on the number of parameters you need to pass.
As another solution you may stop to use redirecting at all.
You may process and render the processing result at once with no POST confirmation alert. You should just manipulate the browser history object:
history.replaceState("", "", "/the/result/page")
See full or short answers

Categories