I am new to PHP, so I am looking for some input on how to make my project a little simpler.
I have a form in which a user can create a list of song, the Submit button then sends it to an intermediate page that saves it to a MySQL database for later use, the intermediate page then forwards them on to the final page that shows them the lyrics of the songs in the order that they chose them.
Originally I had the intermediate page and the final page combined, but ever time a user refreshed the page it would resubmit the data to the DB. What I have works, but it seems like there should be an easier way to accomplish this.
#micahmills: An easier way of stopping duplicate data from being added to the database? Well, it would depend on what you'd consider "easier" -- less code? Less steps? Something else?
What you could do is generate a unique hash or token that submits with the form. This token is then stored in a session after successfully inserting to the database. Attempts to repost the form will then fail because the token sent with the form will be the same as the one stored in the session.
Redirecting to another page after posting to the database is still one of the best and simplest ways of preventing duplicate data being posted though.
Best practice is to redirect after database operation to success / failure page.
You can have form & intermediate combined and a final success page, on failure you need to return back form.
Related
I am helping to make a website in PHP which is an ERP purpose website. We made mockups of a form to collect user details which is split into 4 screens facebook style where the end user keeps clicking next after filling in each partial form. Finally they get the preview and confirmation receipt is generated.
How should I go about this in the backend, I am sure that after the preview I will write the values to the Mysql db and generate a receipt. My question is how do I go about storing the values before the preview?
you can use php sessions to store the variables in a session and then at the end store them all in the database.
http://php.net/manual/en/features.sessions.php
You cannot really answer your question in isolation. It really depends on how your user is going to use the system, whether the information they enter should be persistent, and even whether you know who the user is?
Assuming you know who the user is, and you want to keep failed sessions, my suggestion would be to store the partial responses in a database so you can always access them later.
You can then populate or re-populate the form as you wish. You should also have a "start again" button in this scenario.
More information would help give a better answer.
You can just have one form per screen/page and send these values as parameters to the next page via post or get - it's the most simple way
It is also possible to keep all the form markup on single page and divide form into steps using formToWizard jquery plugin.
http://www.jankoatwarpspeed.com/post/2009/09/28/webform-wizard-jquery.aspx
This way user has all data available when users clicks and back and forth during the steps and you can just have single submit button.
I'm trying to create a form with 3 steps:
fill the form
check if data is correct (show input)
thank you
With an advice of some people here (regarding my previous question) I've changed my way of doing it from mainly PHP + js-validation to mainly js + PHP process data.
I need an advice with how to deal with this now.
Previously I've had a PHP if/else that determined which step to show and kept data in $_SESSION for 2nd step and possible corrections back in 1st step.
Now I'm wondering if I really need two ajax calls (first to process data in order to show it - 2nd form step uses $_SESSION to display data input in 1st step; second to generate e-mail and pdf with given data - same $_SESSION as step2).
Maybe a good solution would be to put data with javascript into 2nd step aswell and use $_SESSION only in the final processing and generating.
What's the common/your approach to this problem?
Here's the normal flow:
User loads page with form on it. Fills it out. Submits it.
You can validate every field as they fill it out (instant feedback which is nice from a user's perspective) or validate using the onSubmit event (in jquery $('#formID').submit). You don't allow them to submit if it doesn't pass, return false from the submit function.
In case they don't have JS enabled (you can try to prevent them from using it w/o JS but in reality they can just use curl -d "value1=foo&value2=foo2&value3=foo3" http://example.org/page/ to get around you) you have to validate the data on the server, too. JS isn't enough.
If it doesn't pass server validation, you can redirect them back to the form using the Location: http://example.org header or echo the form again in the server-side code. If it does pass, you can use it (insert it into db, echo it, email it, whatever).
You save the data in your database and add it to $_SESSION. You echo the data they just entered along with a button "Download PDF" or some such.
They click "Download PDF".
You have all the information you need to create and PDF. You don't have anything to validate but you need to use the $_SESSION information to create the PDF. You should test the $_SESSION to make sure they have valid input from the previous pages or else someone can mimic a post to the page and generate a PDF (perhaps blank though). I generally avoid using data from a $_SESSION as anything but state information -- I'll write to a db on post data (after scrubbing) but if it's in $_SESSION it usually is just stuff that tells me who they are and stores other information about configuration, etc. In your case, I'd have written to a DB in step one and now would use some ID from $_SESSION to pull that record and create the PDF to send it.
I think all of your validation can be easily done in step one and then you separate step 2 into delivery based on the validity of step one.
This is inside a PHP website form.
An example is like:
First page:
-Username:
-Password
Second page:
-Email
-[Checkbox]
Thirdpage:
-Contact Details
-Address
Fourth page:
Review all of the above forms in hard copy but with a back and forward command so that the user does not loose any information when switching between these pages.
Please post.
You could use cookies and do your own sessions with MySQL too. I like doing it like that because the data is easier to access if necessary.
Or you can pass the previous variables to the next page though hidden form elements.. but that can get messy.
You Have to use session. I like Zend_Session.
If you want users to be able to come back later and complete the form (assuming you have some kind of login system, or a way to recognize users), you could still save the data into a database. Make another table, temp_submissions. Keep data in it until the user completes the form and commits the data they send. Once committed, clear the data out of the temp_submissions folder and insert it into the "permanent" table. It may not be practical in this case, or total overkill, but it's an alternative to sessions and cookies.
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
I'm currently developing a page where the user fills out a form, and when submitted they are taken to the next page. When on the next page, I want to have it so that if the user went back to the previous page using the back button, or hit refresh, the submission will not be saved into the DB.
Now I recall reading somewhere that if you had a way to make each submission unique, this issue is averted, but after screwing around for hours on end, for the life of me I cannot recall how this could be done (using PHP), so long story short has anyone ran into this, and if so, what was your solution?
Use the Post/Redirect/Get pattern to avoid this problem. See also Redirect After Post.
Another way is to generate an identifier using uniqid and include it in the form as a hidden input. On submission, store that identifier in a database column marked with a UNIQUE index. This will cause subsequent submissions to throw a SQL error, which your application can handle gracefully.
You can add any confirmation on the second page.
By adding any confirmation box or any button....
by which you can confirm that whether user want to save it or not....
and if you don't want any confirmation...then you can delete the last record....by using managing session...but it is not good practice to fire the query very soon and delete in that kind..
so best way will be by adding any confirmation msg....