Multi page form validation with php - php

This is my first post, so be kind ; )
I'm wanting to create a multi page form with php.
The form will spread over 3 pages, each page will need to validate on the data entered into the form on the client (using jquery validation) and if javascript is disabled, on the server, where error messages need to be displayed beside the related form field.
Upon validation, the data needs to be passed to the next page in the form, preferable using session variables.
The main problem I'm having is that most validation scripts now leave the action="" as being self referring to the current page, and as such post variables cannot be passed onto a different page in the chain of forms.
I want to have a validation script that will validate, and then post to a new page upon clicking the submit button.
Thanks
Peter

You don't have to post to the next page.
You can validate the form fields on the current page, store them in a session, then use a header("location: nextPage.php"); exit(0); redirect to go to the next page.

generally, you can do something like
<form onsubmit="return validateForm();" method="post" action="/wherever">
And this will call your javascript validation form, not submitting the form if the validation form returns false.
You will also need to do server side validation, and I suggest that you store the previous forms validated results into the session, rather than re-posting them (as these wont have to then be re-validated each time!)

You should use the post redirect pattern. Post the variables to the next page (control page), If validations pass then that page does a
header("Location: /page2.php");
after saving the posted variables to the session. If the server side validation fails, then you do a header to the page1.php with the error. pThis way you can use your back button.

I reccommend this JS validator. Very easy to use and doesn't depend on the action="" parameter at all, so you can still set it to whatever you want.

Related

Form submission preview with form validation (PHP)

This is going to sound like a dumb question, so I apologize upfront.
I have a PHP form, with its action posting to itself, so that I can do some validation to make sure text boxes, a few checkboxes and a couple radio buttons are selected. After I confirm there are no form errors, I need to let the user preview what they've entered before letting them submit the information to a database.
For previewing form submission details, logically page1.php would have <form action="page2.php"> and page2.php would allow the user to preview what they've submitted.
But for form validation, logically, the form should submit to itself so that it can validate all required fields are entered while on the same page.
So, is there a way that I can direct the user to a "next page" after the form has validated by submitting to itself, so that they can preview the information?
Note:
I am rewriting a classic ASP form, which does this:
if errorMsg = "" then
response.redirect "verify.asp"
else
session("errorMsg") = errorMsg
response.redirect "default.asp"
end if
I assume in the case of PHP, the "else" portion of a similar conditional would be unnecessary since it already posts to itself, it's only when the error message array is empty that it should redirect to the verify page.
You can use header to perform a redirect:
if(empty($errorMsg)) {
header("Location: verify.php");
exit;
}
Using Mark Heintz's answer and some googling, I figured out the best way to do it is with a combination of Javascript and a meta tag. The meta tag will account for when javascript is disabled.
Redirect in PHP without use of header method
Redirecting to a relative URL in JavaScript
There is also an AJAX way of doing it: Modify the URL without reloading the page

I'm trying to understand PHP_SELF vs ProcessForm.php in the Action field of a <form>

I am new to developing PHP forms and currently trying to understand and learn how they are processed. If I understand it correctly, there are two approaches to using the "Action" attribute.
Method A: Use a separate PHP file to process the form. So in your first file (Form.php), you have the code for the form and submit button. Then in the ProcessForm.php file, you put all of your code for validating the data. In this case, you define the form as
<form method="post" action="ProcessForm.php" >
Method B: Use one PHP file for everything, including the code for the form, submit button, and all validation stuff (including output of error messages if form fields aren't entered properly). Here, you define the the form as
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Right now, I don't understand if one of these methods is more correct or why you would use one vs the other.
I see a form as having four components: HTML for the form, PHP for connecting to MySQL, PHP for input validation/cleaning/error printout, and PHP for moving the data into the MySQL database. I want my form to be able to (upon submitting) work as follows:
If there are one or more errors in the submission process, stay on the same page (stop the submit process) and display relevant error messages, with the fields all still populated (as opposed to blank).
If there are no errors in the submission process, move the data into MySQL, and then display a blank page that says "your data has been submitted successfully" and a link back to my homepage.
Currently I am using Method B, and have implemented #1 above successfully. But I haven't achieved #2. So after this long story, my question is this: Where am I supposed to put those four components? In one file or two, and why?
Neither method is "more correct"; both are just as valid, the one you choose completely depends on the UX you are trying to achieve. Where you are supposed to put the four components depends on whether you are using method A or B.
For method A
If the form is on one page, and you're going to be submitting the data to another page via the action="example.php" attribute, the HTML for the form should (obviously) be on the first page, while everything else should be on the second (example.php) page (all the PHP and SQL). If there's a validation error, you can use header(Location: firstpage.php?error=something) to return users to the original page to fix their mistake.
For method B
If you're doing everything on one page (by putting action="<?php echo $_SERVER["PHP_SELF"]; ?>" or simply action="", both of which do the exact same thing), you should do the validation when a user submits the form on that one page, and if there are no validation errors, insert the data into the database and redirect the user using PHP's header() function.
As you're using method B, this is my more detailed step-by-step process of how I would handle such a form. In the example, firstpage.php is the page a user starts on, and secondpage.php is the page a user is taken to if all the information is correct.
Present the user with your form.
When a user submits the form, the data is submitted via POST or GET (depending on whether you want this information accessible via the URL. If you're not sure, use POST) to firstpage.php where the following PHP is:
PHP:
<?php
if (isset($_POST['submit']) {
// Some validation function
if (do_validation()) {
// Information is valid, insert into db
header(Location: secondpage.php);
die();
}
else {
echo "Error; the information you submitted is not valid.";
}
}
?>
When the user ends up on secondpage.php, you can tell them that the form was successfully submitted.
If you are posting to the script that generates the form itself then you don't even need an action. So method 3 is:
<form method="post">
which is the best version since it will not break and makes it clear that one script renders and handles the post for the form.
Neither of your other methods is ideal. Really you should be looking at (Smarty or something similar) to let you template the HTML and separate the display from the logic. Having said that both options 1 & 2 are perfectly acceptable - if you choose not to use the (superior) option 3 from above.
I can't speak to a "Best Practice", but of the 4 "Components" you mentioned, I think a missing key item is client-side validation as well (javascript typically). This saves you the "round trip" overhead of processing a form that could have already been validated before submitting to the server to handle.
With that being said (and because it's the approach I use), you'll be incorporating some javascript, so what I do is use javascript to validate my fields "on submit" (I override the form's default submit with a javascript event handler), then, if it validates, perform the submit. I do this with ajax, or you can use standard javascript to submit the form. You can even use javascript to set the "action" attribute dynamically (assuming you need to - see #Paul's reasoning why you may not need to).
The php file it submits to typically does 0 presentation work. It connects to the database, saves the "post'ed" info, closes the connection, and returns a status (which is typically why I like ajax because it's easier for me to handle that status response). Based on the status response, you can display an error message (like an alert, a bootstrap modal or info alert, etc.) or a success message/redirect.
While my answer does not offer code, I think the methodology above will serve you better based on your question. The "how" is the easy part once you understand the steps you want to take.

How do you make the browser re-post form data when using the back button?

I guess my question is in understanding the $_POST handling.
So I have two pages that handle 2 forms. Page 1 asks for some information that will be used in page 2. When submitted the form action uses the same page then redirects to next page upon validation, but only handles the data when $_GET variable ?usersubmit=1.
<form action="<?=$_SERVER['PHP_SELF']?>?usersubmit=1" method="post" name="form1">
<input type="text" name="field1">
</form>
So say I have page called form1.php. Upon submit its sent to form1.php?usersubmit=1. The page now assigns the posted data to session variables and then redirects to form2.php via header('location:form2.php').
<?
if($_GET['usersubmit']){
if($_POST['field1']){
#if valid then assign session variable and redirect to next form
$_SESSION['field1'] = $_POST['field1'];
header("location:form2.php");
}else{
#if invalid send error message
$error = true;
}
}
?>
My problem is in when users hit the 'back' button on their browser to edit data from a previous form. The browser doesnt re-post this data it just shows them a blank form. I'd prefer not to use $_SESSION data to fill out the forms because I suspect the re-post method may be a quicker and less problematic fix.
I also tried a javascript redirect instead of a header but browsers are smart enough to not send you back to a page that wants to redirect you so it doesnt work.
any help in understanding this would be greatly appreciated.
thanks.
The only way to handle it is via a session... HTML5 allows for storing of that kind of data but to be honest I wouldnt even look into it as a possibility just yet, altough it does work.
typically the back button will use all of the same get and post variables as was used on the previous locations page load. server side header redirect will not allow you to use the back button to get to the previous page since this redirection is done on the server side.
there are two ways to redirect using javascript window.location which will put your previous location into the browser history and therefore the back button will work, and location.replace which will not put a link in your history, and therefore not allow you to use the back button to get to the previous page.
alternatively, you could just use page two to process page ones form...
Also, you should use htmlentities() in your code. It closes a security vulnerability (see http://www.html-form-guide.com/php-form/php-form-action-self.html for more details).
<form action="<?=$_SERVER['PHP_SELF']?>?usersubmit=1" method="post" name="form1">
should change to something like this below.
<form action="<?=htmlentities($_SERVER['PHP_SELF'])?>?usersubmit=1" method="post" name="form1">

Using same php file to show form and receive the form's data

I have a php page that generates a form. The action attribute of the form is the page itself. After the user submits the form, the same page is loaded, but this time a POST variable is set, so the page runs another script to deal with the incoming data from the form. I do this by using a conditional fork:
if(isset($_POST['var'])){
generate form
}else{
insert $_POST data into database
}
I'd like to know if this is ok or a bad idea.
I agree with Ignacio. Other than that it looks like a fairly standard approach if you don't need more complexity. One very important thing: make sure you are validating and sanitizing that data before it goes into the database.
The bad part is setting the action attribute to the script. Omitting it completely indicates to the browser that it should be posted to the same URL.
You might even want to go to the extent of checking whether the data was submitted thru AJAX to differentiate it from a regular form submission:
if ( $_SERVER['X_REQUESTED_WITH']=='XMLHttpRequest' )
// AJAX

Php, passing data between pages without using the url?

I have a php page that has a form that asks for an e-mail. When you press the send button, it gets to another php page, which gets the form data and does its stuff. I need to then be able to go back to the old page (the one that contained the form) and give it some data so that it will be able to change itself and say "You've sent your e-mail successfully, and will not display the form.
How do I do it?
Sessions probably
http://us2.php.net/manual/en/book.session.php
You can either use sessions or cookies, to not depend on the URL cookies have always to be enabled.
Check the PHP Manual (Sessions and Cookies).
Options:
1) Set a cookie (or use a session variable, which is kind of the same thing)
2) Use a separate thank-you page. After you've processed the form, redirect to http://www.mysite.com/thankyou
3) Process the form on the same page as itself. If your form is at http://www.mysite.com/myform, then at the top of that page have a little
if ($_POST)
// process form
// display thank you
else
// display form
Good luck!
If the user is just seeing data that they've entered anyway, you can just use hidden form fields:
<input type="hidden" id="lang" name="lang" value="en" />
That way you can continue to POST new forms and pass the data down the lane. That's the easiest thing to do without having to write a single extra line of PHP code.
You could also store each section in a database and save each section as-added. That would give you the added benefit of having partial data in the case of a browser crash or whatever, depending on how many parts your form is. You could then pass just an ID to the DB table row and retrieve the data for display.

Categories