PHP form validation on same page with external processing - php

I am trying to wrap up this contact/quote form which has same page validation but external processing. I have set up a variable to go in the form action and the variable/url changes from the same page to the processing page when the form validates. However, it is taking two clicks on the submit button to process the form after all the required fields have been filled in: All the required fields will be filled in, I click submit, the page reloads with the saved data variables and then when I hit submit agin, it finally goes through, sending the email and loading the thankyou page. I have searched the posts here and tried multiple things but have not found a solution. I am definitely not a php expert, still a newbie so this may not be the best way to accomplish this but I'd appreciate any ideas on how to finish this up. Here is what I have:
<?php
....
if (empty($Name) && empty($Company) && empty($Address1) && empty($City) && empty($State) && empty($Phone))
{
echo '<p class="tan">The fields marked with an * are required.</p>';
$Process = 'samepageurl';
}
/*else if (empty($Name) || is_numeric($Name))
{
echo '<p class="tan"><b>Please enter your name.</b></p>';
}*/
else if (empty($Company) || is_numeric($Company))
{
echo '<p class="tan"><b>Please enter your company name.</b></p>';
$Process = 'samepageurl';
}
else if (empty($Address1) || is_numeric($Address1))
{
echo '<p class="tan"><b>Please enter your address.</b></p>';
$Process = 'samepageurl';
}
else if (empty($City) || is_numeric($City))
{
echo '<p class="tan"><b>Please enter your city.</b></p>';
$Process = 'samepageurl';
}
else if (empty($State) || is_numeric($State))
{
echo '<p class="tan"><b>Please enter your state.</b></p>';
$Process = 'samepageurl';
}
else if (empty($Phone) || ctype_alpha($Phone))
{
echo '<p class="tan"><b>Please enter your phone number.</b></p>';
$Process = 'samepageurl';
}
else if (strlen($Phone) < 10 || strlen($Phone) > 12 || ctype_alpha($Phone) || ctype_space($Phone))
{
echo '<p class="tan"><b>Please enter a phone number with an area code.</b></p>';
$Process = 'samepageurl';
}
else if (isset($Name) && isset($Company) && isset($Address1) && isset($City) && isset($State) && isset($Phone))
{
$Process = 'processingurl';
}
?>
<form action="<?php echo $Process; ?>" method="post" class="print" >
<p><input type="hidden" name="recipient" value="responses#url.com"/>
<input type="hidden" name="subject" value="Web Site Response"/>
<input type="hidden" name="redirect" value="thankyou.html"/></p>
... form fields ...
</form>
Thank you in advance!

First check for missing variables, then extract and validate the variables, then serve content based on them.
<?php
function verifyPostContains(&$req) {
global $_POST;
$missing = array();
foreach($req as $var => $_) {
if(!isset($_POST[$var])) {
$missing[] = $var;
}
}
return $missing;
}
$requirements = array('name'=>'','city'=>'','state'=>'',...);
$missing = verifyPostContains($requirements);
if(count($missing)>0) {
$content = formErrorReport($missing);
sendHeaders();
echo $content;
exit();
}
// extract, making sure to sanitize
$name = sanitize($_POST["name"]);
...
$errorHtml = array();
// validate by reference. Effectively call testName($name).
if(failsValidation($name, "testName")) {
$errorHtml [] = generateError(NAME_ERROR, $name);
} else { $requirements["name"] = $name; }
if(failsValidation($city, "testCity")) {
$errorHtml [] = generateError(CITY_ERROR, $city);
} else { $requirements["city"] = $name; }
...
if(count($errorHTML)>0) {
generateErrorPage($requirements, $missing, $errorHTML);
} else { processForm($requirements); }
?>
this code assumes you have functions to do the various bits that need to be done, and has some string constants for generating error HTML.
As a newcomer you may want to google for some tutorials that explain doing form processing using PHP at the server, and JavaScript at the client. If you find a tutorial that gives you code that echos errors while it's testing the data, such as you code does, move along. It's not a good tutorial. If you find one that stops after it finds one error, move along too. If you find one that tells you to make sure the values are right in JavaScript, and then says "we already validated this at the client so we use the values directly in PHP", move along, too. Look for a tutorial that explains:
ensuring there's data in all the form fields, using JavaScript, so the submit button is disabled until there's data for all the fields.
ensuring the data matches your criteria, in PHP, so that people who just POST to your server without ever using your page don't get away with injecting all manner of fun stuff they weren't supposed to be able to do
you generate a page with all the errors explained, if there are any, and the form repopulated with the wrong data, but highlighted as wrong
you process the post request if there are no errors.
(Bonus points if the tutorial explains that a POST request is not required to actually ever generate page content as a response, other than a header that indicates whether or not the POST call was accepted or rejected.)

Related

Multiple IF statements in simple form validation

I am a newbie and trying to implement a simple validation script after reading up, but I can't see how I can have multiple Ifs that will only do an sql insert if all required fields are met. Rather than having the multiple else statements, what is a syntax approach for having all the form validation Ifs together and if one of them fails, then the correct error is shown and the sql is not execute?
if(isset($_POST ['submit'])){
$user_ID = get_current_user_id();
$catErr = $ratingErr = $titleErr = $textErr = "";
if (empty($_POST["category"])) {
$catErr = "Category is required";
} else {
//DO THE INSERT BELOW!
}
if (empty($_POST["rating"])) {
$ratingErr = "Rating is required";
} else {
//DO THE INSERT BELOW!
}
if (empty($_POST["post_name"])) {
$postErr = "Title is required";
} else {
//DO THE INSERT BELOW!
}
if (empty($_POST["text"])) {
$textErr = "Text is required";
} else {
//DO THE INSERT BELOW!
}
//PDO query begins here...
$sql = "INSERT INTO forum(ID,
category,
rating,
post_name,
text
Use one variable for all the error messages and concatenate to it in the branches, so in the end if that variable is still empty string you won't do the insert. (And you don't need any of the empty else blocks that contain nothing but a comment.)
$err = "";
if (empty($_POST["category"])) {
$err .= "<br/>Category is required";
}
if (empty($_POST["rating"])) {
$err .= "<br/>Rating is required";
}
if (empty($_POST["post_name"])) {
$err .= "<br/>Title is required";
}
if (empty($_POST["text"])) {
$err .= "<br/>Text is required";
}
//PDO query begins here...
if($err=='')
{
$sql = "INSERT INTO forum(ID,
category,
rating,
...";
...
}
There are many solutions to your problem. Here are 3 methods of solving your issue.
You could combine all of your if statements like so:
if (empty($_POST['rating']) || empty($_POST'rating']) || ... ) { ... }
and separate them by double pipes.
You could also check the entire array:
if (empty($_POST)) $error = "There was an error!";
You could set a universal error variable and then output it.
A third solution could keep your current syntax but cut down on the amount of lines. You could save lines by doing without brackets. You can create an array and push your errors to the array.
Note: You can use empty() or isset().
// create an array to push errors to
$errors_array = array();
// if a particular field is empty then push the relevant error to the array
if(!isset($_POST['category'])) array_push($errors_array, "Category is required");
if(!isset($_POST['rating'])) array_push($errors_array, "Rating is required");
...
Once you have an array full of errors you can check for them like so:
// if the array is not empty (then there are errors! don't insert!)
if (count($errors_array) > 0) {
// loop through and echo out the errors to the page
for ($i = 0; $i < count($errors_array); $i++) {
echo $errors_array[i];
}
} else {
// success! run your query!
}
You should use javascript to validate the page before it is even processed into a post. This script will run client-side when they hit submit and catch errors before they even leave the page.
Here's a tutorial on how to do something like that: tutorial
Each field can have its own validation parameters and methods, and it will also make the page's code look a lot nicer.
I got it to go with this approach after showdev got me thinking that way. It's not very elegant perhaps, but does the trick, although all the user is taken to a blank page if there are errors and it simple says: Missing category (or whatever). Wondering if I can echo a link or something back to the page with the form from there so the user has an option like "go back and resubmit". Otherwise I will have to handle and display the errors alongside the form which will require a different approach altogether...
if(isset($_POST ['submit'])){
$errors = false;
if(empty($_POST['category'])) {
echo 'Missing category.<br>';
$errors = true;
}
if(empty($_POST['rating'])) {
echo 'Missing rating.<br>';
$errors = true;
}
if(empty($_POST['post_name'])) {
echo 'Missing title.<br>';
$errors = true;
}
if(empty($_POST['text'])) {
echo 'Missing text.<br>';
$errors = true;
}
if($errors) {
exit;
}
// THEN ADD CODE HERE. But how display form again if user makes errors and sees nothing but error message on page if they miss something (which is how it works now)
Generally, if you find yourself repeatedly writing very similar statements, using some sort of loop is probably a better way to go about it. I think what you said about "handling and displaying the errors alongside the form" is really what you need to do if you want the process to be user-friendly. If you put your validation script at the top of the file that has your form in it, then you can just have the form submit to itself (action=""). If the submission is successful, you can redirect the user elsewhere, and if not, they will see the form again, with error messages in useful places.
if (isset($_POST['submit'])) {
// define your required fields and create an array to hold errors
$required = array('category', 'rating', 'post_name', 'text');
$errors = array();
// loop over the required fields array and verify their non-emptiness
foreach ($required as $field) {
// Use empty rather than isset here. isset only checks that the
// variable exists and is not null, so blank entries can pass.
if (empty($_POST[$field])) {
$errors[$field] = "$field is required";
}
}
if (empty($errors)) {
// insert the record; redirect to a success page (or wherever)
}
}
// Display the form, showing errors from the $errors array next to the
// corresponding inputs

PHP form validation that includes SUBMIT button

I have been trying to find a way to validate email in my PHP code. I can only give you parts of my code cause it is really long. What I want to do is to have a person enter their email address by clicking a submit button and if they have entered their email in an unacceptable format, an error message appears. But my problem is: how can I COMBINE a tag WITH "function validate email($field)"? In other words, I know how to combine (PART A) and (PART B), that is easy enough. But what I really want to do is combine (PART B) with (PART C) and not use (PART A) at all. Is that possible? Can I somehow include "isset" inside "function validate email($field)"? I must have a submit button and I must be able to validate the email.
(PART A) <?php //formtest2.php
if (isset($_POST['email'])) $email = $_POST['email'];
else $email = "(Not entered)";
?>
(PART B) <?php
function validate_email($field)
{
if ($field == "") return "No email was entered<br>";
else if (!((strpos($field, ".") > 0) &&
(strpos($field, "#") > 0)) ||
preg_match("/[^a-zA-Z0-9.#_-]/", $field))
return "The email address is invalid<br>";
return "";
}
?>
(PART C) <body>
Your email is: $email<br>
<form method="post" action="brownuniversity.php">
What is your email address?
<input type="text" name="email">
<input type="submit">
</form>
</body>
Hi first of all your gonna want to change this whole thing,
function validate_email($field)
{
if ($field == "") return "No email was entered<br>";
else if (!((strpos($field, ".") > 0) &&
(strpos($field, "#") > 0)) ||
preg_match("/[^a-zA-Z0-9.#_-]/", $field))
return "The email address is invalid<br>";
return "";
}
To this little bit.
function validate_email( $field ){
if (preg_match("/^[^#]+#[a-zA-Z0-9._-]+\.[a-zA-Z]+$/", $field)){
return true;
}
return false;
}
You'll have to do the error messages elsewhere, but this is more portable. ( and I give you a much better Regx for emails ), now you can just do this
if(isset($_POST['email'])){
$email = trim( $_POST['email'] ); //remove any whitespaces from pasting email.
if(validate_email($email)){
//send mail or whatever
}else{
//show errors
}
}
You will still have to check if isset( $_POST['email'] inside the validation isn't really the place to check for it, it should only be concerned with if the data is valid or not, not if there is no data. Also you'll need to check that the form was posted anyway before calling the function and the isset serves both these needs. I updated the answer, you don't really need a validation message on the case that it is not set, because if that is the case they didnt submit the form, it should always be set on form submission.

Input does not pass validation test for strlen

I am making a login system and I have a form with some validation.
However my form seems to be failing to pass the validation even though the data input should pass easily.
See:
http://marmiteontoast.co.uk/fyp/login-register/index.php
When you input a username, it should be over 3 characters. But even if you enter one really long you get the error message: The username is less than 3 characters.
EDIT: There was an issue in my copying from formatting that caused a missing }. I've corrected this. It wasn't the issue.
This is the if statement for the username pass. So it seems like it is not getting past the first test:
if (isset($_POST['username'])){
$username = mysql_real_escape_string(trim($_POST['username']));
$_SESSION['status']['register']['username'] = $username;
if(strlen($username) > 3){
if(strlen($username) < 31){
if(user_exists($username) === true){
$_SESSION['status']['register']['error'][] = 'That username is already taken. Sorry, please try again with a different username.';
}else{
// passed
}
} else {
$_SESSION['status']['register']['error'][] = 'The username is greater than 30 characters.';
}
} else {
$_SESSION['status']['register']['error'][] = 'The username is less than 3 characters.';
}
} else {
$_SESSION['status']['register']['error'][] = 'The username is not entered.';
}
And this is the HTML for the username:
<form method="post" action="register.php">
<div class="username">
<label class="control-label" for="inputUser">Username</label>
<input type="text" id="inputUser" name="username" placeholder="Username" value="<?php echo $usern_value; ?>" />
</div>
You can see the site here: http://marmiteontoast.co.uk/fyp/login-register/index.php
Session
The index page does use sessions.
It starts with this:
<?php
session_start();
?>
And kills the session at the end of the file:
<?php
unset($_SESSION['status']);
?>
But in the file it starts new sessions which store the inputs. This is so if you make a mistake, it still holds your info so you can adjust it rather than having the fill in the form again. Here is an example of where it grabs the username and saves it, then outputs it.
<?php
if(isset($_SESSION['status']['register']['username'])){
$usern_value = $_SESSION['status']['register']['username'];
} else {
$usern_value = "";
}
?>
value="<?php echo $usern_value; ?>" />
This is the user-exists function:
function user_exists($username){
$sql = "SELECT `id` FROM `users` WHERE `username` = '".$username."'";
$query = mysql_query($sql);
$result = mysql_num_rows($query);
if($result == 1){
// username does already exist
return true;
}else{
// username doesn't exist in the database
return false;
}
}
Ah, I can see the problem from your website link. When the error pops up ("The username is less than 3 characters."), try refreshing your browser. I expected to receive a browser warning that says the data would be resubmitted to the server — because you are in a post form — but I did not.
So, what does this mean? It means that immediately after validation failure, you are redirecting back to the same screen, and — unless you are using a session to preserve this information — your $_POST data will be lost. Commonly in the case of validation failure with this sort of form, you must prevent that redirect and render inside the post operation, which keeps the user's input available to you. The redirect should only occur if the form input was successful (i.e. it saves to the data and/or sends an email).
Edit: I should have seen the $_SESSION in the original post. OK, so the strategy is to write things to the session, redirect regardless of validation outcome, and to save error messages to the session. I wonder whether you are not resetting the session errors array when you're posting the form? Immediately after your first if, try adding this:
if (isset($_POST['username'])){
$_SESSION['status']['register']['error'] = array(); // New line
Unless you have something to make the session forget your errors, they will be stored until you delete your browser's cookie.
You have missed a closing brace } on this line:
if(user_exists($username) === true){
} else{// **missed the closing brace before the else**
// passed
}
Why is your logic so complex?
if (strlen($username) < 3) {
// too short
} elseif (strlen($username) > 31) {
// too long
} elseif (true === user_exists($username)) {
// already registered
} else {
// passed
}

Variable doesn't get defined/updated after function processes?

I have coded some alerting system.
But let's not look at the system itself, Let's look at how will the system know that the system really did sent the alert/error to the browsing user.
I have made something so when you randomly go to ?alert=name, without doing any error, it will say 'No errors'.
But if the system makes you go to ?alert=name, it will echo the error.
How I handle posts
function postComment() {
if (!empty($_POST['name']) || !empty($_POST['comment'])) {
$comment = mysql_real_escape_string(htmlentities($_POST['comment']));
$guest = mysql_real_escape_string(htmlentities($_POST['name']));
}
$guestId = 1;
if (empty($guest)) {
$alert = 1;
return header('location: index.php?alert=name');
}
if (empty($comment)) {
$alert = 2;
return header('location: index.php?alert=comment');
}
if (!isset($_COOKIE['alreadyPosted'])) {
mysql_query("INSERT INTO `comments` (`comment_guest`, `guest_id`, `comment`, `comment_date`, `comment_time`) VALUES ('$guest', '$guestId', '$comment', CURDATE(), CURTIME())") or die(mysql_error());
header('Location: index.php?action=sucess');
setcookie(alreadyPosted, $cookieId+1, time() + 60);
} else {
$alert = 3;
header('location: index.php?alert=delay');
}
}
As you see, to check if user really getting that error, I will set $alert to whatever error number it is.
And to check if hes getting the error I will use this:
if (isset($_GET['alert']) == 'name') {
if ($alert == 1) {
echo 'hai';
} else {
echo 'No errors';
}
}
You will probably wonder why I am doing it this way.., well because I use 1 function for post, and my post function goes under the form, and i want the alerts to display up to the form.
Problem:
The variable either doesn't get set to the number that it is supposed to when running the function,
or.. something is blocking it from it.. I don't know..
My guess: Because the check for errors is located up to the postComment function before the variables even get set?
<?php
if (isset($_GET['alert']) == 'name') {
if ($alert == 1) {
echo 'hai';
} else {
echo 'No errors';
}
}
?>
<form action="index.php" method="POST">
<input type="text" name="name" placeholder="Your name here" class="field">
<textarea class="textarea" name="comment" placeholder="Your comment here..."></textarea>
<input type="submit" name="send" class="blue_button" value="Post Comment">
</form><input type="submit" name="" id="margin" class="blue_button" value="See all messages">
<br />
<?php
//Show the comments
showComments();
if (isset($_POST['send'])) {
postComment();
}
if (isset($_GET['delete']) == "comment"){
deleteComment();
}
echo '<br />';
?>
If it is, what is the solution?
Thanks!
Please don't start with the story about mysql_ function, I understood & I will use PDO instead, but I am using mysql_ at the moment for testing purposes
The problem is that you're redirecting on an error, and so the $alert variable does not get carried over.
To fix the problem add the alert type to the $_GET parameters:
function postComment()
{
// ...
if (empty($guest))
{
header('location: index.php?alert=name&alert_type=1');
exit;
}
// ...
}
And then when you check for the error:
if (isset($_GET['alert']) && 'name' == $_GET['alert'])
{
if (isset($_GET['alert_type']) && '1' == $_GET['alert_type'])
{
echo 'hai';
}
else
{
echo 'No errors';
}
}
Note also that I fixed the error here:
isset($_GET['alert']) == 'name'
That doesn't do what I think you think it does. What you want is:
isset($_GET['alert']) && 'name' == $_GET['alert']
(Excuse the order of the comparison; I prefer to have variables on the right for comparisons as it will cause a parse error if you miss a = -- much better than having it run but not do what you expect)
if you are a newbie, you better consider using client side scripting (viz javascript) for validation as using server side validation will simple make the process longer. but as you are facing problems, this might give you the solution.
as you are redirecting the page to index.php?alert=name', so $alert is never set initially when the page loads itself. when you call the function postcomment(), $alert is initiated but immediately destroyed when the system redirects. And as $alert never holds a value when you randomly visit the page, it shows no error.

Trying To Create A Javascript Alert Window That Doesn't Reload The Page When OK Is Clicked

I have a PHP form that I've set up with a POST method. When all the fields aren't filled out I have a Javascript alert box that pops up and states 'Please fill out all fields!' When I click 'OK' on the alert window it reloads the form behind it clearing all the data that was entered. Is there a function that can keep the alert box's OK button from reloading the entire page? Here's my code:
<?php
if (isset($_POST['brandname']) && isset($_POST['firstname']) && isset($_POST['lastname']) && isset($_POST['email']) && isset($_POST['website'])){
$brandname = $_POST['brandname'];
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST['email'];
$website = $_POST['website'];
if(!empty($brandname) && !empty($firstname) && !empty($lastname) && !empty($email)){
$to = 'matt#miller-media.com';
$subject = 'Submission Form';
$body = $firstname;
$headers = 'From: '.$email;
if (#mail($to, $subject, $body, $headers)){
}
}else{
echo '<script type="text/javascript">
window.alert("Please fill out all fields!")
</script>';
}
}
?>
You are alerting your user after posting response ... in this case I would re-post the whole form again with its values set to $_POST or variables that were set using it, for example :
<input type='text' name='brandname' value='<?php echo $_POST['brandname'];?>' />
or :
<input type='text' name='brandname' value='<?php echo $brandname; ?>' />
and so on
But in this case I recommend using client-side validation on the form (Using javascript)
Yeah i assume you need something like this:
<script type="text/javascript">
function do_some_validation(form) {
// Check fields
if (! /* Contition 1 */ ) return false;
if (! /* Contition 2 */ ) return false;
if (! /* Contition 3 */ ) return false;
form.submit();
}
</script>
<form onsubmit="do_some_validation(this) return false;" action="script.php" method="post">
// Fields
</form>
This will only submit the form once all JavaScript conditions in do_some_validation are met... Please note this is not advised over and above PHP validation, this should be used purely for comfort for the user not having to submit the page when there's something Javascript can validate against
For any further PHP validation messages, you can either pass variables into GET or SESSION, eg.
<?php
session_start();
if (count($_POST)) {
if (!/* Condition 1 */) $_SESSION['error'] = "Message";
if (!isset($_SESSION['error'])) {
// Proceed
} else header("Location: script.php");
}
?>
On the page:
<?php if (isset($_SESSION['errir'])) {
echo $_SESSION['error'];
unset($_SESSION['error']);
} ?>
Since your code sample is PHP-code, it seems that you are posting the form and validate it server-side, and then you show an alert if any field is empty? In that case, the page has already reloaded, before the alertbox is shown. You are mixing server-side and client-side code.
If you want to show an alert box if the user hasn't filled in all the fields (without reloading the page), you will have to do the validation with JavaScript. You should still keep your PHP-validation as well though!
If you use jQuery for instance, you could do something like this:
$("#your-form-id").submit(function(){
// Check all your fields here
if ($("#input-field-1").val() === "" || $("#input-field-2").val() === "")
{
alert("Please fill out all fields");
return false;
}
});
It can of course be done without jQuery as well. In that case you can use the onsubmit attribute of the form tag to call a JavaScript function when the form is posted, and within that function you do the validation of the form, show an alert box if any field is empty, and then return false from the function to prevent the form from being posted to the server.

Categories