PHP Form Spam Prevention - php

Please bear with me as I am a graphic designer with some coding knowledge, but not near as much as a developer. And after many hours of tinkering and asking Google, I've decided to ask y'all directly!
I've been working on building a contact form for my website. So far so good, except for one thing. I would like to add a simple spam prevention field.
I've added a field "spamcheck" with the question 6+2=? but I do not know how to code the PHP to require that the value specifically be 8. As long as the other fields are correctly filled out, the form will submit regardless of the number entered here despite any attempt to mess with the code (thus why you will see my $spamcheck variable but the current coding only requires that it have a value like the rest of the fields).
I have included the PHP, the validation the PHP calls to, and the form. Apologies if the form has some excess code; I have tried many different versions of PHP form tutorials to no avail.
And of course, thank you very much for your help! :)
Here is the PHP code I have placed directly in the web page:
<?php
define("EMAIL", "email#gmail.com");
if(isset($_POST['submit'])) {
include('validate.class.php');
//assign post data to variables
$name = trim($_POST['name']);
$email = trim($_POST['email']);
$budget = trim($_POST['budget']);
$deadline = trim($_POST['deadline']);
$message = trim($_POST['message']);
$spamcheck = trim($_POST['spamcheck']);
//start validating our form
$v = new validate();
$v->validateStr($name, "name", 1, 50);
$v->validateEmail($email, "email");
$v->validateStr($budget, "budget");
$v->validateStr($deadline, "deadline");
$v->validateStr($message, "message", 1, 1000);
$v->validateStr($spamcheck, "spamcheck");
if(!$v->hasErrors()) {
$from = "website.com"; //Site name
// Change this to your email address you want to form sent to
$to = "email#gmail.com";
$subject = "Hello! Comment from " . $name . "";
$message = "Message from " . $name . "
Email: " . $email . "
Budget: " . $budget ."
Deadline: " . $deadline ."
Message: " . $message ."";
mail($to,$subject,$message,$from);
//grab the current url, append ?sent=yes to it and then redirect to that url
$url = "http". ((!empty($_SERVER['HTTPS'])) ? "s" : "") . "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
header('Location: '.$url."?sent=yes");
} else {
//set the number of errors message
$message_text = $v->errorNumMessage();
//store the errors list in a variable
$errors = $v->displayErrors();
//get the individual error messages
$nameErr = $v->getError("name");
$emailErr = $v->getError("email");
$budgetErr = $v->getError("budget");
$deadlineErr = $v->getError("deadline");
$messageErr = $v->getError("message");
$spamcheckErr = $v->getError("spamcheck");
}//end error check
}// end isset
?>
This is the validate.class.php which it calls to:
<?php
class validate {
public $errors = array();
public function validateStr($postVal, $postName, $min = 1, $max = 1000) {
if(strlen($postVal) < intval($min)) {
$this->setError($postName, ucfirst($postName)." is required.");
} else if(strlen($postVal) > intval($max)) {
$this->setError($postName, ucfirst($postName)." must be less than {$max} characters long.");
}
}// end validateStr
public function validateEmail($emailVal, $emailName) {
if(strlen($emailVal) <= 0) {
$this->setError($emailName, "Please enter an Email Address");
} else if (!preg_match('/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[#][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/', $emailVal)) {
$this->setError($emailName, "Please enter a Valid Email Address");
}
}// end validateEmail
private function setError($element, $message) {
$this->errors[$element] = $message;
}// end logError
public function getError($elementName) {
if($this->errors[$elementName]) {
return $this->errors[$elementName];
} else {
return false;
}
}// end getError
public function displayErrors() {
$errorsList = "<ul class=\"errors\">\n";
foreach($this->errors as $value) {
$errorsList .= "<li>". $value . "</li>\n";
}
$errorsList .= "</ul>\n";
return $errorsList;
}// end displayErrors
public function hasErrors() {
if(count($this->errors) > 0) {
return true;
} else {
return false;
}
}// end hasErrors
public function errorNumMessage() {
if(count($this->errors) > 1) {
$message = "There was an error sending your message!\n";
} else {
$message = "There was an error sending your message!\n";
}
return $message;
}// end hasErrors
}// end class
?>
And here is the form html/php:
<span class="message"><?php echo $message_text; ?></span>
<?php if(isset($_GET['sent'])): ?><h2>Your message has been sent</h2><?php endif; ?>
<form role="form" method="post" action="webpage.php#contact">
<div class="form-group">
<input type="text" name="name" class="form-control" id="name" value="<?php echo htmlentities($name); ?>" placeholder="Full Name" required>
<label for="exampleInputName"><i class="icon-tag"></i></label>
<span class="errors"><?php echo $nameErr; ?></span>
<div class="clearfix"></div>
</div>
<div class="form-group">
<input type="email" name="email" class="form-control" id="email" value="<?php echo htmlentities($email); ?>" placeholder="Email" required>
<label for="exampleInputEmail1"><i class="icon-inbox"></i></label>
<span class="errors"><?php echo $emailErr; ?></span>
<div class="clearfix"></div>
</div>
<div class="form-group">
<input type="text" name="budget" class="form-control" id="budget" value="<?php echo htmlentities($budget); ?>" placeholder="Budget" required>
<label for="exampleInputBudget1"><i class="icon-usd"></i></label>
<span class="errors"><?php echo $budgetErr; ?></span>
<div class="clearfix"></div>
</div>
<div class="form-group">
<input type="text" name="deadline" class="form-control" id="deadline" value="<?php echo htmlentities($deadline); ?>" placeholder="Deadline" required>
<label for="exampleInputDeadline"><i class="icon-calendar"></i></label>
<span class="errors"><?php echo $deadlineErr; ?></span>
<div class="clearfix"></div>
</div>
<div class="form-group textarea">
<textarea rows="6" name="message" class="form-control" id="message" value="<?php echo htmlentities($message); ?>" placeholder="Write Message" required></textarea>
<label for="exampleInputMessage"><i class="icon-pencil"></i></label>
<span class="errors"><?php echo $messageErr; ?></span>
<div class="clearfix"></div>
</div>
<div class="form-group">
<input type="text" name="spamcheck" class="form-control" id="spamcheck" value="<?php echo htmlentities($spamcheck); ?>" placeholder="Spam check: 6+2=?" required>
<label for="exampleInputSpamCheck"><i class="icon-lock"></i></label>
<span class="errors"><?php echo $spamcheckErr; ?></span>
<div class="clearfix"></div>
</div>
<button type="submit" id="submit" name="submit" value="submit" class="btn btn-large">Send Message</button>
</form>

In the PHP script where you generate the form, you should save the correct answer to the question in a $_SESSION variable.
Then, in the PHP script that receives this form data, you should verify that what was submitted for that question matches the right answer in the $_SESSION variable.
There are a bunch of tutorials on how to use sessions in PHP.
Basically, it comes down to:
form.php
<?php
session_start();
$_SESSION['captcha_right_answer'] = somehow_generate_this();
?>
handler.php
<?php
session_start();
if ($_INPUT['captcha_answer'] != $_SESSION['captcha_right_answer']) {
// Show "bad captcha" message, re-show form, whatever
}
else {
// Captcha good - go on with life
}
?>

Check this out as an alternative to a captcha. Then you could use your existing class to validate the field. Say your hidden field has a name "fakeField" You could validate it with your validateSTR method via..
$v->validateStr($fakeField, "fakeField",0,0);
Since your str check is checking > and < instead of >= and <= this will return true when the length is exactly 0. This might be an easier solution for someone with little code knowledge to integrate.
Alternatively, if you're stuck on using a captcha of sort, and you know what you expect the value to be, you could add a method to check against the value you're expecting.
The method:
public function validateCaptcha( $value,$name, $expectedValue) {
if(trim($value) != $expectedValue) {
$this->setError($name, "Captcha Incorrect");
}
}
then change the line of code
$v->validateStr($spamcheck, "spamcheck");
to
$v->validateCaptcha($spamcheck, "spamcheck", '6');
This isn't the best solution since there are so many powerful captchas out therebut it's easy to use.

Another simple method is to capture the time the page loads and compare it to the time the form was submitted. If the difference was too short, exit the page. spambots are quick; people are slow. Spambots may figure out various fields - even do math - but they are never going to wait around for more than a few seconds.
It takes only two lines, one in the form:
<input name="timeloaded" type="hidden" value="<?php echo time();?>" />
and one in the form processing code:
if(!(is_numeric($_POST['timeloaded'])) || time()-$_POST['timeloaded']<30) {header("Location: index.php"); exit;}
This one is for a form that no human can fill out in less than 30 seconds. Change that for the length of form you use.

Related

I don't know what i did wrong on my code, the error message for php form validation stopped working [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I don't know what I did wrong on my code, the error message for php form validation stopped working.
It was working perfectly until i added value attribute to the input so that the user input will persist even if the page refresh and didn't deliver due to typeError.
The form does'nt show any error again but my reason for adding the value attribute is working.
I'm learning php, please help me to understand why i'm having the issue.
I don't understand because i'm not getting any error from php.
This is my code
<?php
// empting the value variables when user have'nt typed anything to prevent error. This is the shorthand of typing samething that's going to have the same value
$email = $title = $ingredients = '';
// put out the error on the html instead of echoing it
// so i used array so that i can neatly put out all the errors instead of using different variables for all
$error = array('email' => '', 'title' => '', 'ingredients' => '');
// check if the form was clicked and retrive the values sent
// i will achieve this by using a default method called isset() and i will check if value is contained in the form using the submit btn, this is because when a user clicks on the form submit, the user have entered a value
if(isset($_POST['submit'])){
// check if the field submited is empty
// we achieve this using a default method called empty()
// we check them one field at a time
// check for email
if(empty($_POST['email'])){
$error['email'] = ' Email is empty';
} else {
$email = $_POST['email'];
}
// check for title
if(empty($_POST['title'])){
$error['title'] = ' Title is empty';
} else {
$title = $_POST['title'];
}
// check for ingredients
if(empty($_POST['ingredients'])){
$error['ingredients'] = ' Ingredients is empty';
} else {
$ingredients = $_POST['ingredients'];
}
}
?>
<!DOCTYPE html>
<html lang="en">
<?php include 'template/header.php'?>
<form action="form.php" method="POST">
<div class="input_div">
<label >Email :</label>
<input type="text" name="email" value=" <?php echo $email ?> ">
<div class="error_msg"><?php echo $error['email']; ?></div>
</div>
<div class="input_div" >
<label >Pizza Title :</label>
<input type="text" name="title" value=" <?php echo $title ?> " >
<div class="error_msg"><?php echo $error['title']; ?></div>
</div>
<div class="input_div" >
<label >Ingredients (comma seperated) :</label>
<input type="text" name="ingredients" value=" <?php echo $ingredients ?> ">
<div class="error_msg"><?php echo $error['ingredients']; ?></div>
</div>
<div class="input_div" >
<input type="submit" class="submitBtn" name="submit" value="Submit">
</div>
</form>
<?php include 'template/footer.php' ?>
</html>
Other then the issues with whitespace in your inputs you should also be aware of XSS when inserting the values back into the form (like using " would break the form) and also don't populate the errors till needed, this will allow you to easily continue and do the success step without needing to loop over the $errors array and it also allows you to hide the <div class="error_msg"></div> element and only show when there is an error.
Also your missing <head> and <body>, presuming they are in the includes, but doing it that way would make it rather difficult to add additional elements or scripts.
<?php
$email = $title = $ingredients = '';
$error = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// check for email
if (empty($_POST['email'])) {
$error['email'] = 'Email is empty';
} else {
$email = $_POST['email'];
}
// check for title
if (empty($_POST['title'])) {
$error['title'] = 'Title is empty';
} else {
$title = $_POST['title'];
}
// check for ingredients
if (empty($_POST['ingredients'])) {
$error['ingredients'] = 'Ingredients is empty';
} else {
$ingredients = $_POST['ingredients'];
}
if (empty($error)) {
// do some thing with $email, $title, $ingredients
die(header('Location: ./thank-you.php'));
}
}
function xss_safe($value) {
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
?><!DOCTYPE html>
<html lang="en">
<?php include 'template/header.php' ?>
<form action="form.php" method="POST">
<div class="input_div">
<label>Email :</label>
<input type="text" name="email" value="<?= xss_safe($email) ?>"/>
<?= isset($error['email']) ? '<div class="error_msg">'.$error['email'].'</div>' : '' ?>
</div>
<div class="input_div">
<label>Pizza Title :</label>
<input type="text" name="title" value="<?= xss_safe($title) ?>"/>
<?= isset($error['title']) ? '<div class="error_msg">'.$error['title'].'</div>' : '' ?>
</div>
<div class="input_div">
<label>Ingredients (comma seperated) :</label>
<input type="text" name="ingredients" value="<?= xss_safe($ingredients) ?>"/>
<?= isset($error['ingredients']) ? '<div class="error_msg">'.$error['ingredients'].'</div>' : '' ?>
</div>
<div class="input_div">
<input type="submit" class="submitBtn" name="submit" value="Submit">
</div>
</form>
<?php include 'template/footer.php' ?>
</html>
Seeing as your error checking is merely for empty/missed input fields it's easier to just make the inputs required as per HTML5. Here's a simplified version using placeholders for information after the form has been submitted.
Warning: If you are going to be inserting this data into a MySQL table, you need to sanitize the inputs first!
<?php
$email = $title = $ingredients = "";
if (isset($_POST["submit"])) {
$email = $_POST["email"];
$title = $_POST["title"];
$ingredients = $_POST["ingredients"];
}
echo "
<form method='POST'>
<label>Email:</label>
<input type='email' name='email' placeholder='$email' required>
<label>Pizza Title:</label>
<input type='text' name='title' placeholder='$title' required>
<label>Ingredients (comma seperated):</label>
<input type='text' name='ingredients' placeholder='$ingredients' required>
<input type='submit' name='submit' value='Submit'>
</form>
";
?>

How to stay in the footer section after submit? #php

I need a little help with PHP sessions or something similar from someone who is well versed in PHP sessions, and who has an understanding for someone who is not.
Somebody told me that it can be done with PHP sessions or that is not possible? There are some answers that can be done with Ajax but my question is - Can it be done with PHP sessions and how? Well, everything works for me - it inserts data into the database and throws out validation errors, but this is my problem: I'm doing MVC and I don't want to refresh my page after the submission so that the user has to scroll down to see validations (because I have $msg and $errors in footer), so I want the viewport to be in the same place after the submit where the messages are written - in footer. I would be very grateful if someone can see and give me a concrete answer of what I need where to put or from where what to delete. I believe the little thing is in the Controller.
P.S. Here are 1. index.php (pijaca.php) page composed of parcels, 2. pijaca-footer.php on which the form is located, 3. routes.php on which it goes from the form and 4. Controller.php.
I tried everything: putting "id" in the form and than call it from Controller - doesn't work, looked for advice and answers on the net, I probably googled something bad (it will come with time as well as experience), but I couldn't manage. Thanks in advance!
<?php
$ime = isset($ime)?$ime:"";
$prezime = isset($prezime)?$prezime:"";
$telefon = isset($telefon)?$telefon:"";
$errors = isset($errors)?$errors:[];
session_start();
?>
<?php include'pijaca-nav.php'; ?>
<?php include'pijaca-header.php'; ?>
<?php include'pijaca-about.php'; ?>
<?php include'pijaca-photo-1.php'; ?>
<?php include'pijaca-story.php'; ?>
<?php include'pijaca-photo-2.php'; ?>
<?php include'pijaca-features.php'; ?>
<?php include'pijaca-footer.php'; ?>
<footer id="contact" class="footer">
<div class="footer__box">
<form action="routes.php" id="form" class="form" method="post">
<input type="text" class="form__input" name="firstname" placeholder="First Name" value="<?php echo $ime ?>"><span>*<?php if(array_key_exists('firstname', $errors)) echo $errors['firstname'] ?></span>
<input type="text" class="form__input" name="lastname" placeholder="Last Name" value="<?php echo $prezime ?>"><span>*<?php if(array_key_exists('lastname', $errors)) echo $errors['lastname'] ?></span>
<input type="text" class="form__input" name="telephone" placeholder="Telephone No." value="<?php echo $telefon ?>"><span>*<?php if(array_key_exists('telephone', $errors)) echo $errors['telephone'] ?></span>
<button class="btn btn--green btn--form" type="submit" name="page" value="contactus">Contact us</button>
</form>
<h5 class="heading-5 heading-5--footer-box-1">
<?php if(isset($msg)) echo $msg ?>
</h5>
</div>
</footer>
<?php
require_once'../controller/Controller.php';
$controller = new Controller();
$pageGet = isset($_GET['page'])?$_GET['page']:"index";
$pagePost = isset($_POST['page'])?$_POST['page']:"index";
$page = ($pageGet != "index")?$pageGet:$pagePost;
switch ($page) {
case 'contactus':
$controller->contactus();
break;
}
<?php
require_once'../model/DAO.php';
class Controller{
public function contactus() {
$ime = isset($_POST['firstname'])?$_POST['firstname']:"";
$prezime = isset($_POST['lastname'])?$_POST['lastname']:"";
$telefon = isset($_POST['telephone'])?$_POST['telephone']:"";
$errors = [];
if (empty($ime)) {
$errors['firstname'] = "Please enter your name";
}
if (empty($prezime)) {
$errors['lastname'] = "Please enter your lastname";
}
if (empty($telefon)) {
$errors['telephone'] = "Please enter your telephone";
} else {
if (preg_match('/^[0-9 +_-]*$/', $telefon)) {
} else {
$errors['telephone'] = "Please enter a number";
}
}
if (count($errors) == 0) {
$dao = new DAO();
$podacikorisnika = $dao->korisnik($ime, $prezime, $telefon);
$msg = "Sucsses!";
include 'pijaca.php';
} else {
$msg = "Please enter all fileds";
include 'pijaca.php';
}
}
}

Form validation in php - the error and success message display at the same time

I'm learning coding and created a simple form where error messages are
displayed just below each input field. However, when I check the form
the success message appears at the same time as error messages instead
of displaying when all the fields are correctly entered and form
validated. Can you please help. Thank yo in advance. Here is my
code.
</php>
$errorMessage = "";
$successMessage = "";
$emailError = "";
$emailconfirmError = "";
$nameError = "";
$messageError = "";
$servicesError = "";
$name = $email = $emailConfirm = $services = $message = "";
$email = isset($_POST['email']) ? $_POST['email'] : '';
$emailConfirm = isset($_POST['emailConfirm']) ? $_POST['emailConfirm'] : '';
if ($_POST) {
if (!$_POST['email']) {
$emailError .="The email is required";
}
if (!$_POST['emailConfirm']) {
$emailconfirmError .="Please confirm your email <br>";
}
if ($_POST['emailConfirm'] && $email != $emailConfirm) {
$emailconfirmError .="The email addresses do not match <br>";
}
if (!$_POST['name']) {
$nameError .="The name field is required <br>";
}
if (!$_POST['services']) {
$servicesError .="Please select a service required <br>";
}
if (!$_POST['message']) {
$messageError .="The message field is required <br>";
}
if ($_POST['email'] && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) === false) {
$emailError .= "The email address is invalid.<br>";
}
if ($name = $email = $emailConfirm = $services = $message != "") {
echo $emailError;
echo $emailconfirmError;
echo $name;
echo $services;
echo $message;
}else {
$emailTo = "kamala_guliyeva#hotmail.com";
$services = $_POST['services'];
$message = $_POST['message'];
$headers = "From: ".$_POST['email'];
if (mail($emailTo, $services, $message, $headers)) {
$successMessage = '<div class="alert alert-success" role="alert">Thank you for your message. We\'ll get back to you ASAP!</div>';
} else {
$errorMessage = '<div class="alert alert-danger" role="alert"><p>Your message couldn\'t be sent - please try again</div>';
}
}
}
and HTML
<div id="quote">
<div class="container">
<h2 class="section-title">Request a Quote</h2>
<hr align="left" width="8%" class="style-one">
<br>
<div><? echo $errorMessage.$successMessage; ?></div>
<form id="quoteForm" method="post">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<input type="email" class="form-control" style="height:60px" id="email" name="email" placeholder="Your email">
<label class="error" id="emailError"><?php echo $emailError; ?></label>
</div>
<div class="form-group">
<input type="email" class="form-control" style="height:60px" id="emailConfirm" name="emailConfirm" placeholder="Re-type your email">
<label class="error" for="e-mailConfirm" id="emailconfirmError"><?php echo $emailconfirmError; ?></label>
</div>
<div class="form-group">
<input type="name" class="form-control" id="name" style="height:60px" name="name" placeholder="Your Name">
<label class="error" for="name" id="nameError"><?php echo $nameError; ?></label>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<select class="form-control" id="services" name="services" style="height:60px">
<option value="">Select Services</option>
<option value="Installation">Installation</option>
<option value="Repair">Repair</option>
<option value="Service and Maintenance">Service and Maintenance</option>
</select>
<label class="error" for="services" id="servicesError"><?php echo $servicesError; ?></label>
</div>
<div class="form-group">
<textarea class="form-control" id="message" name="message" placeholder="Message" style="height: 163px;" cols="35"></textarea>
<label class="error" for="message" id="messageError"><?php echo $messageError; ?></label>
</div>
</div>
</div>
<div class="form-row text-center">
<div class="col-12">
<button type="submit" style="width:10rem" class="btn quoteButton pt-3 pb-3 text-align-center">Get a Quote</button>
</div>
</div>
</form>
</div>
</div>
You've a few problems there...
So first thing is how you are doing your checks.
if(!$_POST) {
is not a valid way of checking that a post has occurred you need to do something like
if(isset($_POST) && !empty($_POST)) {
would be more appropriate as you are checking if the POST array is actually set and then that it is not empty the && operator is a short circuit operator so if either condition isn't met then the check will fail.
Similarly on your comparisons saying if(!$_POST['email']) { isn't valid because you're effectively asking "if the email part of the post array is not true" where as you need to be asking "if it's not blank and is a valid email address"
You need to be aware of the difference between = == and === operators. You can find some more information here: The 3 different equals
And also the filter_var function here: http://php.net/manual/en/function.filter-var.php
if($_POST['email']!=="" && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
//all good
} else {
//set your error message
}
you can use regular expressions to validate 'name' see preg_match in the manual http://php.net/manual/en/function.preg-match.php
Aside from all of this if you want to have real time monitoring of the fields and the error messages etc you're going to have to look at incorporating Javascript and using AJAX to communicate with your script and then parse the response back into the appropriate div.
Have a look at Rasmus 30 second AJAX tutorial will give you a starting point for this http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX-Tutorial.html
However it is better practice to do both client and server side validation hope this helps even if it is not a complete answer per sé.

PHP Form Validation: Form will submit regardless if it passes validation or not [duplicate]

This question already has answers here:
Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
(3 answers)
PHP form validation not working, allowing invalid submissions to be sent
Closed 4 years ago.
So I have asked a similar question but in the comments, I was told a possible answer however it didn't work so I'm posting another one. The situation is slightly different so I didn't know whether to edit and update the other one or make a new one.
Anyway, I have a form and a PHP script that is supposed to validate the form data when the user submits and for now(testing purposes) if it does not pass the validation an array with strings should print.
Berfore I go on here is the html:
<form method="post" action="mail3.php" class="col-12" id="form-book">
<div class="row">
<div class=" form-group col-12">
<p>Fill out the form below to tell me about your problem. <strong>Any problems to do with technology, all the solutions.</strong> Just tell me what you can, however the more info you give the better.</p>
</div>
<div class="form-group col-6">
<label></label>
<input id="name" name="name" placeholder="Name" type="text" required="required" class="form-control here bottom"> <span class="error">
</div>
<div class="form-group col-6">
<label></label>
<input id="phone" name="phone" placeholder="Phone#" type="text" required="required" class="form-control here bottom"> <span class="error">
</div>
<div class="form-group col-12">
<label></label>
<input id="email" name="email" placeholder="Email (Optional)" type="text" class="form-control here bottom"> <span class="error">
</div>
<div class="form-group col-6">
<input data-provide="datepicker" id="date" name="date" placeholder="Pick a date" required="required" class="form-control here bottom">
</div>
<div class="form-group col-6">
<input type="text" id="time" name="time" placeholder="Choose the best time" required="required" class="form-control here bottom timepicker">
</div>
<div class="form-group col-12">
<label></label>
<textarea id="message" name="message" cols="40" rows="5" class="form-control" required="required" aria-describedby="messageHelpBlock"></textarea>
<span id="messageHelpBlock" class="form-text text-muted">Tell me a little about whats going on or what you need help with.</span>
</div>
<div class="form-group col-12">
<button name="submit" type="submit" class="btn btn-primary">Send your message</button>
</div>
</div>
<!--row-->
</form>
PHP:
<?php
date_default_timezone_set("Pacific/Honolulu"); //set the DateTimeZone
function test_input($data) { //test input func that checks data
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
if (isset($_POST['submit'])) {
$name = $_POST['name'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$date = $_POST['date'];
$time = $_POST['time'];
$message = $_POST['message'];
$subject = "Appointment Booked";
$email = filter_var($email, FILTER_SANITIZE_EMAIL); //clean email
$mailTo = "itguy#johnpuaoi.com";
$dateTested = test_input($date);
$timeTested = test_input($time);
$errors = []; //set errors arrray
//funcs will check each input and if an error is detected it will add a string to errors array
//if no errors are found the input is then passed into xTested variable
function validateName($input) {
if (empty($input)) { //check if empty
return $errors[] = "Your name is required."; //if empty add string to errors array
} elseif (is_int($input)) { //check if input is an interger
return $errors[] = "That is not a valid name."; //if is interger add string to errors array
} else {
return $nameTested = test_input($input); //return tested input variable
}
}
function validatePhone($input) {
if (empty($input)) { //check if empty
return $errors[] = "Your phone number is required."; //add string to array if empty
} elseif (!preg_match("/^[0-9]{3}-[0-9]{4}-[0-9]{4}$/", $input)) { //check if input does not match
return $errors[] = "That is not a valid name."; //add string to array if no match
} else {
return $phoneTested = test_input($input); //return tested input variable
}
}
function validateEmail($input) {
if (empty($input)) { //check if empty
return $errors[] = "Your email is required.";//add string to array if empty
} elseif (filter_var($email, FILTER_VALIDATE_EMAIL)) {
return $errors[] = "That is not a valid email.";
} else {
return $emailTested = test_input($input); //return tested input variable
}
}
function validateMessage($input) {
if (empty($input)) { //check if empty
return $errors[] = "Your message can't be empty.";//add string to array if empty
} else {
return $messageTested = test_input($input); //return tested input variable
}
}
validateName($name); //call validate funcs
validatePhone($phone);
validateEmail($email);
validateMessage($message);
$headers = "From: ".$emailTested;
$txt = "An appointment was booked by ".$nameTested.".\n\n".$dateTested." #".$timeTested.".\n\n".$messageTested;
if ($errors == null) { //if errors array is empty
mail($mailTo, $subject, $txt, $headers); //mail data
header("Location: index.php?mailsend"); //redirect to home
} else {
print $errors; //print errors to test if validate funcs work
}
}
?>
Now I have created validate functions for a set data type - name, email, phone and message. It checks the input and if an error occurs then a string is added to the errors array. If no error is found then the input is passed to a variable to tells php it has been tested for errors.
IMPORTANT In the last question I asked, in the comments someone pointed out that I did not have anything stopping the mail func even if the data did not pass validation. So to fix that I included an if statement at the bottom that checks if the errors array is empty. If it is then the mail func is called, if it isn't then for testing purposes the errors array is printed.
I test the script by purposely entering invalid data but the form submits anyway. What is allowing the script to still mail the form data?
Now if you could not tell already, I am new to php so forgive me if I its something simple. I apologize in advance also if I should have just edited the first question.

PHP - Redisplay forms with valid values in fields and error messages where validation fails

I have created a PHP form to take 4 text fields name, email, username and password and have set validation for these. I have my code currently validating correctly and displaying messages if the code validates or not.
However, I would like for it to keep the correctly validated fields filled when submitted and those that failed validation to be empty with an error message detailing why.
So far I have the following code, the main form.php:
<?php
$self = htmlentities($_SERVER['PHP_SELF']);
?>
<form action="<?php echo $self; ?>" method="post">
<fieldset>
<p>You must fill in every field</p>
<legend>Personal details</legend>
<?php
include 'personaldetails.php';
include 'logindetails.php';
?>
<div>
<input type="submit" name="" value="Register" />
</div>
</fieldset>
</form>
<?php
$firstname = validate_fname();
$emailad = validate_email();
$username = validate_username();
$pword = validate_pw();
?>
My functions.php code is as follows:
<?php
function validate_fname() {
if (!empty($_POST['fname'])) {
$form_is_submitted = true;
$trimmed = trim($_POST['fname']);
if (strlen($trimmed)<=150 && preg_match('/\\s/', $trimmed)) {
$fname = htmlentities($_POST['fname']);
echo "<p>You entered full name: $fname</p>";
} else {
echo "<p>Full name must be no more than 150 characters and must contain one space.</p>";
} }
}
function validate_email() {
if (!empty($_POST['email'])) {
$form_is_submitted = true;
$trimmed = trim($_POST['email']);
if (filter_var($trimmed, FILTER_VALIDATE_EMAIL)) {
$clean['email'] = $_POST['email'];
$email = htmlentities($_POST['email']);
echo "<p>You entered email: $email</p>";
} else {
echo "<p>Incorrect email entered!</p>";
} }
}
function validate_username() {
if (!empty($_POST['uname'])) {
$form_is_submitted = true;
$trimmed = trim($_POST['uname']);
if (strlen($trimmed)>=5 && strlen($trimmed) <=10) {
$uname = htmlentities($_POST['uname']);
echo "<p>You entered username: $uname</p>";
} else {
echo "<p>Username must be of length 5-10 characters!</p>";
} }
}
function validate_pw() {
if (!empty($_POST['pw'])) {
$form_is_submitted = true;
$trimmed = trim($_POST['pw']);
if (strlen($trimmed)>=8 && strlen($trimmed) <=10) {
$pword = htmlentities($_POST['pw']);
echo "<p>You entered password: $pword</p>";
} else {
echo "<p>Password must be of length 8-10 characters!</p>";
} }
}
?>
How can I ensure that when submit is pressed that it will retain valid inputs and empty invalid ones returning error messages.
Preferably I would also like there to be an alternate else condition for initial if(!empty). I had this initially but found it would start the form with an error message.
Lastly, how could I record the valid information into an external file to use for checking login details after signing up via this form?
Any help is greatly appreciated.
Try using a separate variable for errors, and not output error messages to the input field.
You could use global variables for this, but I'm not fond of them.
login.php
<?php
$firstname = '';
$password = '';
$username = '';
$emailadd = '';
$response = '';
include_once('loginprocess.php');
include_once('includes/header.php);
//Header stuff
?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES, "utf-8");?>" method="post">
<fieldset>
<p>Please enter your username and password</p>
<legend>Login</legend>
<div>
<label for="fullname">Full Name</label>
<input type="text" name="fname" id="fullname" value="<?php echo $firstname ?>" />
</div>
<div>
<label for="emailad">Email address</label>
<input type="text" name="email" id="emailad" value="<?php echo $emailadd; ?>"/>
</div>
<div>
<label for="username">Username (between 5-10 characters)</label>
<input type="text" name="uname" id="username" value='<?php echo $username; ?>' />
</div>
<div>
<label for="password">Password (between 8-10 characters)</label>
<input type="text" name="pw" id="password" value="<?php echo $password; ?>" />
</div>
<div>
<input type="submit" name="" value="Submit" />
</div>
</fieldset>
</form>
<?php
//Output the $reponse variable, if your validation functions run, then it
// will contain a string, if not, then it will be empty.
if($response != ''){
print $response;
}
?>
//Footer stuff
loginprocess.php
//No need for header stuff, because it's loaded with login.php
if($_SERVER['REQUEST_METHOD'] == 'POST'){//Will only run if a post request was made.
//Here we concatenate the return values of your validation functions.
$response .= validate_fname();
$response .= validate_email();
$response .= validate_username();
$response .= validate_pw();
}
//...or footer stuff.
functions.php
function validate_fname() {
//Note the use of global...
global $firstname;
if (!empty($_POST['fname'])) {
$form_is_submitted = true;
$trimmed = trim($_POST['fname']);
if(strlen($trimmed)<=150 && preg_match('/\\s/', $trimmed)){
$fname = htmlentities($_POST['fname']);
//..and the setting of the global.
$firstname = $fname;
//Change all your 'echo' to 'return' in other functions.
return"<p>You entered full name: $fname</p>";
} else {
return "<p>Full name must be no more than 150 characters and must contain one space.</p>";
}
}
}
I wouldn't suggest using includes for small things like forms, I find it tends to make a mess of things quite quickly. Keep all your 'display' code in one file, and use includes for functions (like you have) and split files only when the scope has changed. i.e your functions.php file deals with validation at the moment, but you might want to make a new include later that deals with the actual login or registration process.
Look at http://www.php.net/manual/en/language.operators.string.php to find out about concatenating.

Categories