Display form confirmation message in the same page: best practice - php

I've seen this behaviour in many websites and web applications but I'm not able to find a "clean and standard" way to reproduce it: the user fills in the form, submits it and then, after a successful validation, the form is reloaded with a message on top saying something like "The item has been saved". No problems so far, what I can't understand is how they keep displaying the confirmation message if that specific page is reloaded, but when the user goes to another page and then returns to the original one (the one containing the form) the message is not there anymore. There seems to be no get or post data, so I'm assuming session variables or cookies are used instead, but how do they know when to keep and when to unset them? Or maybe I'm wrong and there is some other way... help me, please!

My guess would be that they used a session variable which unsets itself the moment that page is accessed. So if they try to access it again, they are simply redirected.

Maybe the page with the form doesn't have any "unset" session variable but the others do ?

Related

How to disable browser back history for a specific route in php? [duplicate]

I am working on a my site to allow users to take test so they can see how much they know of a particular subject. I am running into a little problem though. Once a user submits the test for grading, how do I prevent them from going back to the test page? I am on a Mac with Safari running and when I click the back button in my web browser after I submit the test it leaves all of the answers I answered filled out. I want it do this: When a user submits a test and they click the back button in their web browser it redirects them to the main test page.
I am using PHP and MYSQL. I even have the test pages setup so that the user must come from a certain url (I am using HTTP_REFERER) and I have tried other stuff such as sessions but I cannot seem to figure this out. Any help is greatly appreciated.
You don't stop them.
Instead change your application so that it still works even if they go back. You can embed a unique number in a hidden field on the page and if they resubmit the same test twice you can detect it and display an appropriate error message. You should also think about what should happen if they modify the unique number.
If you don't want people to post different answers once they have already answered, all you have to do is check, in the script that accepts the test for grading, that the user has never submitted the test before. If you don't, a clever student will always be able to to circumvent your protection by sending an appropriate request directly to that script.
If you don't want people to see previous answers (for instance, if you have two people grade their tests on the same computer), consider using AJAX on the test page to submit the answers and then erase them from the fields. This way, most browsers will not remember the answers and the back button will not un-erase data that was erased by JavaScript.
At the top of the grade page, put the following:
session_start();
$_SESSION['testcomplete'] = 'yes';
Then at the top of each page of the test, put this:
session_start()
if ($_SESSION['testcomplete'] == 'yes') {
header("Location:cheater.php");
}
You could simulate there being no page to go back to. From one page, generate each test page using jQuery, and provide no way to go back, only forward. The back button would take them to the page before they ever launched the test, and you could allow them to launch the test again and generate the right part where they should be. This would be pretty easy, if you haven't gone too far in development the current way.
You could run javascript that clears out all the answers. You might also just allow one submission so that subsequent submissions don't get processed. HTTP_REFERER is usually sent, but can be spoofed and forged by an altered browser.
On the top of the script POST-ing the answers, do a check whether you have the test results in the database for the current user for this test. If you do, redirect to results.
if(get_test_results($user)){
$test_url = get_test_url($user);
header( "Location: $test_url" ) ;
}
Disabling the back button is not a good idea.
I was facing a similar problem making an online examination myself
what I did is
I provided a session variable such that if the user pastes the previous page's URL in the address bar then on loading the page the page is automatically forwards to the next desired page. Whether the page whose URL was mentioned is the being visited the first time or being revisited is determined by the value of the session variable
If the user instead of loading the page does a go back via the browser button the it automatically redirects to the next page in history as :
javascript:window.history.forward(1);
Hope this helps :)
http://www.htmlgoodies.com/tutorials/buttons/article.php/3478911/Disabling-the-Back-Button.htm you should be able to do it in javascript.

What do I do after the user registers in PHP form?

I'm building my first PHP site, and I've got the registration process working even using the new PDO API, however I don't know what to do when I'm done successfully registering the user?
So, in other words, the register.php page doesn't have any markup, I just used it to POST to so I could build the record.
I'm sorry guys, I just don't yet understand how most people use PHP.
You could handle it in many different ways.
Have one page with markup and one page for handling post. (which is how you have it now). Your register.php page can pickup $_POST variables from your form, validate them and if ok then show quick message showing ("Well done!") echo "Well done";
You can also instead of showing echo "Well done", redirect to another page something like thank-you.php that will just show you have registered message. This is good because if your user tries to refresh the page it will not attempt to generate new registration. (See http://php.net/manual/en/function.header.php)
Handle everything in one php file. eg. If $_POST is empty then show registration form. If $_POST has items, check and validate and show message (either success or please fix following data and show form. (Example here: http://www.html-form-guide.com/php-form/php-form-tutorial.html)
Obviously there is a lot more to sending forms - validation/sanitizing being the major part of it, but since you are just learning basics I think you can forget about it for now. Just always remember to research first and try not to invent the wheel (See example http://php.net/manual/en/function.htmlspecialchars.php to help you with sanitizing)
That's up to you. Generally, you will display a registration confirmation page to let the user know that their registration worked. If you are sending an activation email, now would be a good time to do so, and to let them know as well. Also, a link to the members area from that page is helpful. You can also log the user in directly from the registration confirmation page.

Implementing a 'Email to a friend' functionality. How to pass variables to the next page without using form, session and cookies?

I'm trying to create a "Email to friend" page using php. The objective of this page is that users can share the page that they are viewing with their friends.
When a user clicks on the 'share' link, it'll redirect user to a page that asks a user to input their own email address and a recipient email address. The subject will be the previous page title and the email body will be the URL of the previous page plus whatever a user may want to include.
I've got the whole concept here but I'm stuck on the implementation stage. I can't seem to figure the best way to pass the previous page title and the page URL to the share page.
Here's what I have thought of so far.
Using POST and GET method doesn't
seem to fit in because there is no
forms involved when a user clicks on
the share link.
Using session and cookies would be
very tedious as it requires assigning
and modifying the cookie / session
each time a user views a page.
Passing variables in URL would make
simply make the URL long and somewhat
undesirable.
Is there any other way that I could use to pass the page title and page url to the next page? I'm open for other suggestions on how I could implement this idea differently. Thanks in advance.
As far as I can see, passing the URL as a GET parameter is indeed the ideal solution.
http://example.com/share.php?url=http%3a%2f%2fwww.example.com
note that
You need to URL-encode the URL you are passing using urlencode()
the total resulting URL should not be longer than 2-4 kilobytes due to restrictions in some browsers.
I don't understand why POST and GET are not an option. Just because there isn't a form on the page doesn't mean you can't put one there. Can the link be turned into a button? If you don't like the look of a button, use CSS. Putting a form on the page would only take a few lines.
I would go for the session approach, even though you consider it tedious. This is called "flash messages" and it's quite commonspread. Zend Framework has these out of the box, CodeIgniter has a neat contributed library for it... Basically, you just need to write a few helper functions and you're set. To get the barebones functionality, you need:
adding a new message
retrieving a message/all messages
clearing messages (could be called after fetching messages)
The messages stored in the session will persist until you clear them, they are immune to redirecting and once you write your helper functions, it'll be as easy as:
//before redirect:
setFlash('You have successfully logged in!');
//after redirect
echo fetchFlash();
clearFlash(); //if fetchFlash doesn't call it automatically
So I wouldn't call it tedious, really. Rather a butt-saver.

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

How to stop someone from going back to previous page?

I am working on a my site to allow users to take test so they can see how much they know of a particular subject. I am running into a little problem though. Once a user submits the test for grading, how do I prevent them from going back to the test page? I am on a Mac with Safari running and when I click the back button in my web browser after I submit the test it leaves all of the answers I answered filled out. I want it do this: When a user submits a test and they click the back button in their web browser it redirects them to the main test page.
I am using PHP and MYSQL. I even have the test pages setup so that the user must come from a certain url (I am using HTTP_REFERER) and I have tried other stuff such as sessions but I cannot seem to figure this out. Any help is greatly appreciated.
You don't stop them.
Instead change your application so that it still works even if they go back. You can embed a unique number in a hidden field on the page and if they resubmit the same test twice you can detect it and display an appropriate error message. You should also think about what should happen if they modify the unique number.
If you don't want people to post different answers once they have already answered, all you have to do is check, in the script that accepts the test for grading, that the user has never submitted the test before. If you don't, a clever student will always be able to to circumvent your protection by sending an appropriate request directly to that script.
If you don't want people to see previous answers (for instance, if you have two people grade their tests on the same computer), consider using AJAX on the test page to submit the answers and then erase them from the fields. This way, most browsers will not remember the answers and the back button will not un-erase data that was erased by JavaScript.
At the top of the grade page, put the following:
session_start();
$_SESSION['testcomplete'] = 'yes';
Then at the top of each page of the test, put this:
session_start()
if ($_SESSION['testcomplete'] == 'yes') {
header("Location:cheater.php");
}
You could simulate there being no page to go back to. From one page, generate each test page using jQuery, and provide no way to go back, only forward. The back button would take them to the page before they ever launched the test, and you could allow them to launch the test again and generate the right part where they should be. This would be pretty easy, if you haven't gone too far in development the current way.
You could run javascript that clears out all the answers. You might also just allow one submission so that subsequent submissions don't get processed. HTTP_REFERER is usually sent, but can be spoofed and forged by an altered browser.
On the top of the script POST-ing the answers, do a check whether you have the test results in the database for the current user for this test. If you do, redirect to results.
if(get_test_results($user)){
$test_url = get_test_url($user);
header( "Location: $test_url" ) ;
}
Disabling the back button is not a good idea.
I was facing a similar problem making an online examination myself
what I did is
I provided a session variable such that if the user pastes the previous page's URL in the address bar then on loading the page the page is automatically forwards to the next desired page. Whether the page whose URL was mentioned is the being visited the first time or being revisited is determined by the value of the session variable
If the user instead of loading the page does a go back via the browser button the it automatically redirects to the next page in history as :
javascript:window.history.forward(1);
Hope this helps :)
http://www.htmlgoodies.com/tutorials/buttons/article.php/3478911/Disabling-the-Back-Button.htm you should be able to do it in javascript.

Categories