I have a form that I am trying to add some steps that will minimize spam without forcing the end user to input some random number text series.
here’s an example of my form code:
<form action="form.php" method="post">
<label for="Name" style="some style">Enter your name:</label>
<input type="text" name="name">
<label for="Email" style="some style">Your email address:</label>
<input type="text" name="email">
<label for="City" style="some style">City:</label>
<select id="some ID" name="city" value="PQS" >
<option value="" selected disabled>Choose A City</option>
<option value="City1">City1</option>
<option value="City2">City2</option>
<input type="submit" value="Sign Up Now" class="button" id="subscribe">
</form>
<p id="error" style="some style">OOPS! Something went wrong. Please try again.</p>
<p id="success" style="some style">Success! We’ll contact you shortly</p>
My current form.php looks somewhat like this:
<?php
$emailmanager = 'me#myemail.com';
$name = $_POST['name'];
$visitor_email = $_POST['email'];
$city = $_POST['city'];
error_reporting(0);
$email = trim($_POST['email']);
$Ok = ereg("^([a-zA-Z0-9_\.-]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+)) ([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", $email);
if ($Ok) {
mail($emailmanager,'New Contact Request','You have a new contact request for homes in '.$_POST['city'].' from '.$_POST['name'].' ','From: '.$_POST['email'].' ');
if( !ereg("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$",$UNameFrm) )
{
echo 1;
}
}
else
{
echo 0;
}
What I am trying to incorporate is a blank field that can deter the spambots, and I found an awesome code to use but I would like to incorporate it into my code above. See below the code i found:
<?php
// if the url field is empty
if(isset($_POST['url']) && $_POST['url'] == ''){
// put your email address here
$youremail = 'you#yoursite.com';
// prepare a "pretty" version of the message
$body = "This is the form that was just submitted:
Name: $_POST[name]
E-Mail: $_POST[email]
Message: $_POST[message]";
// Use the submitters email if they supplied one
// (and it isn't trying to hack your form).
// Otherwise send from your email address.
if( $_POST['email'] && !preg_match( "/[\r\n]/", $_POST['email']) ) {
$headers = "From: $_POST[email]";
} else {
$headers = "From: $youremail";
}
// finally, send the message
mail($youremail, 'Contact Form', $body, $headers ); } // otherwise, let the spammer think that they got their message through ?>
This code i found requires me to create a class
.antispam { display:none;}
...and add some html in my form
<label for="url" class="anti spam">Leave This Empty:</label>
<input type="text" name="url" />
how do I incorporate these 2 together? There are some things that are obvious to me, like adding
$url = $_POST['url'];
to my form.php on the next line following $city. My challenge is where to incorporate
// if the url field is empty
if(isset($_POST['url']) && $_POST['url'] == '')
and
if( $_POST['email'] && !preg_match( "/[\r\n]/", $_POST['email']) ) {
$headers = "From: $_POST[email]";
} else {
$headers = "From: $youremail";
}
into my form.php without screwing up my form function entirely. Any help would be appreciated, and I hope I made my question clear
You generate a random token for each guest session (or even user's login or form page) and save in database.
When printing forms, add one hidden input.
<input type="hidden" name="token" value="token_value_RANDOM1234567890">
When user submits form, then you check if given token is valid (or belongs to authenticated user, in login case). If belongs, then he's a valid user, else is a bot (not so simple as that). By the way, it complicates the process of spamming, do not block all ways of spamming. And you get an improvement on your website security.
Hope it helps.
You should put the class on the input, not the label, since labels aren't sent to the server.
<input type="text" class="antispam" name="antispam" value="">
Browsers won't send inputs that have display: none;, so if you receive this input, it means it came from an automated spammer.
if (isset($_POST['antispam'])) {
// Reject as spam
}
I use this honeypot tactic all the time. The trick is to create a field on the form that will not be visible to humans with eyes, but will be seen by bots. I usually give it an attractive name like "url" like your example does.
<input class="honeypot" name="url" value="url" />
Then you use CSS to push it off the screen:
input.honeypot {
position:absolute;
left:-5000px;
}
That can go anywhere in your stylesheet, or in a <style> tag in your html, or right on the input
<input style="position:absolute; left:-5000px;" name="url" value="url" />
Then you need a test in the validation code which is the action PHP:
if (isset($_POST['url'] && 'url' != $_POST['url']) {
header("location:/routing-error");
}
This gives the bot a 404 for the page "routing-error"
Related
I have a simple contact form. Works great - except the several emails I get daily. Spam!! I want to add a simple verification question (such as 'Zebras are black and...') where only a certain answer its accepted or the form will not be sent. How do I go about this?
The antispam isnt working at all!
Html:
<form action="submit.php" class="col4" method="post">
<p>Your name: <input name="name" type="text" size="100" />
</p>
<p>Your email: <input name="email" type="text" size="100" /> </p>
<p><input name="website" type="text" class="website"/></p>
<p class="antispam">Leave this empty: <input type="text" name="url" />
</p>
<p>Message: <textarea name="message" cols="100"></textarea>
</p>
<p><input type="submit" value="Send" /></p>
</form>
CSS:
form .website{ display:none; } /* hide because is spam protection */
PHP:
<?php
# spam protection
if (isset($_POST["website"]) && $_POST["website"] == "") {
# your php code to mail here
} else {
http_response_code(400);
exit;
}
// if the url field is empty
if (isset($_POST['url']) && $_POST['url'] == '') {
// put your email address here
$youremail = 'admin#napleswebgraphics.com';
// prepare a "pretty" version of the message
$body = "This is the form that was just submitted<br />
:
Name: $_POST[name]
E-Mail: $_POST[email]
Message: $_POST[message]";
// Use the submitters email if they supplied one
// (and it isn't trying to hack your form).
// Otherwise send from your email address.
if ($_POST['email'] && !preg_match("/[\r\n]/", $_POST['email'])) {
$headers = "From: $_POST[email]";
} else {
$headers = "From: $youremail";
}
// finally, send the message
mail($youremail, 'Contact Form', $body, $headers);
} // otherwise, let the spammer think that they got their message through ?>
<h1 align="center">Thank You!</h1>
<div align="center">I'll get back to you as soon as possible! Click here to go back to the main page.
</div>
I want a specific answer to be the ONLY thing that allows the form to go through.
Adding this check is very simple. In your form html, add a new field:
<p>Zebras are black and...: <input name="animal" type="text" /></p>
Then, in your PHP you can check for its existence and bail early if it's wrong. Add this to the top of your PHP file:
if (empty($_POST['animal']) || $_POST['url'] !== 'white') {
http_response_code(400);
die('wrong answer');
}
I'm all new to PHP and JavaScript, just learning web development and I'm trying all sort of things in my free time, however, there is one thing I cannot find a solution for.
I have a form that would be collecting only 4 datas, Name, Date of Birth, Email and Phone number. All fields are required for further data procession. I literally tried every single thing I found on Google, but it still doesn't work. The form simply saves all sort of data into the database, without checking the input fields.
Later on I'd like the code to validate the form, display any errors on the same page not on a different ".php" one and also send 2 emails one as a confirmation for the person and one for notifying me about a form submission. What should I do/change to achieve that? I feel quite stuck atm.
my form:
<form class="contactform" id="cfrm" action="process.php" method="post">
<div class="f-data">
<input class="f-error" name="uname" placeholder="NAME" type="text" required="required" data-error="Name is required.">
</div>
<div class="clear"></div>
<div class="f-data">
<select name="birthday" id="forminput" aria-required="true" aria-invalid="false">
<option value="11">11</option>
<option value="12">12</option>
</select>
<select name="birthyear" id="forminput" aria-required="true">
<option value="1900" selected="selected">1900</option>
<option value="2001">2001</option>
</select>
</div>
<div class="f-data">
<input class="f-error" name="uemail" placeholder="EMAIL" type="text" required="required" data-error="Email is required.">
</div>
<div class="f-data">
<input class="f-error" name="uphone" placeholder="PHONE" type="text" required="required" data-error="Phone is required.">
</div>
<div class="clear"></div>
<div class="submit">
<p>
<input type="submit" value="submit" name="submit">
</p>
</div>
and the process.php
<?php
require "connection.php";
require "others/phpmailer/PHPMailerAutoload.php";
//form data
$connection = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);
$Name = $connection->real_escape_string($_POST['uname']);
$DoB = $connection->real_escape_string($_POST['birthyear'] . '-' .
$_POST['birthmonth'] . '-' . $_POST['birthday']);
$inputDoB = date("Y-m-d",strtotime($DoB));
$Email = $connection->real_escape_string($_POST['uemail']);
$Phone = $connection->real_escape_string($_POST['uphone']);
if (strlen($agree) == 0) $agree = 0;
// validating
if(isset($_POST['submit']));
{
if(empty($_POST['uname']))
{
$msg_name = "You must enter name";
$name_subject = $_POST['uname'];
$name_pattern = '/^[a-zA-Z ]*$/';
preg_match($name_pattern, $name_subject, $name_matches);
if(!$name_matches[0])
$msg2_name = "Only alphabets and white space allowed";
}
if(empty($_POST['uemail']))
{
$msg_email = "You must enter your email";
$email_subject = $_POST['uemail'];
$email_pattern = '/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/';
preg_match($email_pattern, $email_subject, $email_matches);
if(!$email_matches[0]) $msg2_email = "Must be a valid email address";
}
if($_POST['uphone'])
{
$phone = $_POST['uphone'];
preg_match('/^[_a-z0-9-]+(.[_a-z0-9-]+)*#[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z {2,3})$/i', $phone, $phone_match);
if(!$phone_match[0]) $msg_phone = "Must be a valid phone number";
if(strlen($phone)!='8') $msg2_phone = "Must be at least 8 characters long";
}
}
//save to db
$query = "INSERT INTO form (Name,DoB,Email,Phone,Date) VALUES ('$Name','$DoB','$Email','$Phone', CURRENT_TIMESTAMP)";
$success = $connection->query($query);
if (!$success) {
die("Couldn't enter data: ".$connection->error);
}
echo "Thank You For Contacting Us";
?>
As for your display of inline error messages, what I would recommend doing is only making use of one page to handle the main form 'logic', and another include() to represent the raw HTML markup fo the form itself. The 'logic' page would be where you direct your visitors as the 'form'.
Inside of your if(isset($_POST['submit'])), you would check the data that is submitted. If it is valid, you go ahead and process the submission. If it is invalid, you raise an error, and show the form again. The form is also shown by default.
This is shown in the following semi-pseudocode:
$error = ''; // Nothing is wrong at first
if(isset($_POST['submit'])) {
// Raise error messages based on submission
if(empty($_POST['uname'])) {
$error = "You must enter name";
}
if(empty($_POST['email'])) {
$error = "You must enter email";
}
// Show the form if there are errors
if ($error) {
include('form.php');
}
// Process the submission if there aren't
else {
//$query = ...
mail($Email, $email_subject, $msg_email);
}
}
else {
include('form.php');
}
With form.php conditionally checking for $error:
<?php
if ($error !== '') {
// Output the error message in a fancy way
echo "<span class='error'>" . $error . "</span>";
}
?>
<form> ... </form>
As for sending the two emails, you're practically there! You already have $msg_email, $email_subject and $Email. You're just looking to make use of PHP's mail() function:
mail($Email, $email_subject, $msg_email);
Note that you'll probably want to add the fourth parameter (headers) in there as well.
I also note that you currently have a semicolon in if(isset($_POST['submit']));{, which will prevent the block from triggering. Make sure you remove this.
Hope this helps! :)
While formatting your code for question clarity I think I found the issue.
You have 2 formatting issues that would cause this sort of issue.
1) You have a semicolon preventing your if from being a block conditional
if(isset($_POST['submit']));
with that semicolon there the block will run separated and simply act as a scope separator.
2) Your Regex isn't complete
preg_match('/^[_a-z0-9-]+(.[_a-z0-9-]+)*#[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z {2,3})$/i', $phone, $phone_match);
In your last capture group (.[a-z {2,3}) you don't have a closing square bracket for the [a-z] character selector it should be (.[a-z]{2,3})
I would also point out that you are setting$msg_name and $msg2_name but I don't see them used anywhere and you don't stop execution on error so the process just continues through to the query even though you said you want it to stop.
My question might be quite a simple one, but I am very new to PHP and have tried to piece everything together after reading, but have run into some problems. I have read through possible duplicates of this post and tried as much as possible to put those solutions into my code but to no avail.
Objective:
Name and email validation (just not empty and in email format)
Details sent to indicated email
Basic sanitizing of code (mysqli escape and htmlspecialchars) (Understand that there is PDO, but would like to stick to this).
After successful submission, reload page with same website (fields empty) but with message in indicating message sent or error. Am trying header("Location: "). Would prefer not to introduce AJAX as I have no knowledge of it. Is this possible? Have also read about using action:"" to stay on same page, but how do I run my mail.php if my action is ""? Have also tried include: mail.php, or renaming my mail.php to index.php, but still did not succeed.
Current problems faced:
I do receive an email but with empty fields, i.e. inputs are not reflected although I did enter some values in the form. These are the values I received:
From:
Phone:
etc....
Page does direct to header location. But div not updated with $success variable, i.e. no message updated to show in div.
Please refer to my php and html file below:
PHP:
<?php
$link = mysqli_connect("host", "username", "password", "dbname");
$NameErr=$EmailErr=$Success="";
$Name=$Email=$Company=$JobTitle=$Phone=$Message="";
function sanitize($link,$entry) {
$entry = mysqli_real_escape_string($link,$entry);
$entry = htmlspecialchars($entry);
return $entry;
}
if (empty($_POST["Name"])) {
$nameErr = "Name is required";
}
else if (!preg_match("/^[a-zA-Z ]+$/", $Name)) {
$NameErr = "Only letters and spaces allowed";
}
else {
$Name = sanitize($link, $_POST["Name"]);
}
if (empty($_POST["Email"])) {
$EmailErr = "Email is required";
}
else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$EmailErr = "Invalid email format";
}
else {
$Email = sanitize($link, $_POST["Email"]);
}
$Company = sanitize($link, $_POST["Company"]);
$JobTitle = sanitize($link, $_POST["JobTitle"]);
$Phone = sanitize($link, $_POST["Phone"]);
$Message = sanitize($link, $_POST["Message"]);
$formcontent=" From: $Name \n Phone: $Phone \n Company: $Company \n Job Title: $JobTitle \n Phone: $Phone \n Message: $Message";
$recipient = "myemail#gmail.com";
$subject = "Contact Form";
$mailheader = "From: $Email \r\n";
if (mail($recipient, $subject, $formcontent, $mailheader)){
$Success = "Message sent, thank you for contacting us!";
header("location:Contact.Us.html");
}
else($Success = "Sorry, we are unable to process your submission.");
?>
HTML form:
<form action="mail.php" method="POST">
<ul class="contact">
<li>
<label for="Name">Name<span class="red">*</span></label>
<p><input id="Name" name="Name" type="text" required/></p>
</li>
<li>
<label for="Email">Email<span class="red">*</span></label>
<p><input id="Email" name="Email" type="email" required/></p>
</li>
<li>
<label for="Company">Company</label>
<p><input id="Company" name="Company"/></p>
</li>
<li>
<label for="JobTitle">Job Title</label>
<p><input id="JobTitle" name="JobTitle"/></p>
</li>
<li>
<label for="Phone">Phone</label>
<p><input id="Phone" name="Phone"/></p>
</li>
<li>
<label for="Message">Message</label>
<p><textarea id="Message" wrap="soft" name="Message"></textarea></p>
</li>
</ul>
<br>
<p><input id="submit" type="submit" value="Send!" /></p>
<div class="success"><? =$Success; ?></div>
</form>
Would appreciate your reply to resolve any of the problems mentioned above. Would also appreciate if you could highlight other areas of possible security concerns. Thanks!
Also, upon implementing recommendation of sanitize($link,$entry), I am receiving inputs in my email for the variables: Company and Job Title.
Hence, I further changed all my variables name to first letter capital i.e. $message to $Message and aligned it throughout my form's input 'id', 'name' and 'for'. After which, I managed to receive input for the additional variables of Phone and Message.
Currently, am only not receiving values in my email for variables Name and Email. Perhaps there is an error with my 'if else if' portion of the php code. Will figure and update again. In the meantime, if any recommendation, please continue to update too. Thanks for your help!
As #headmax pointed, you need to also pass the link parameter to the sanitize function
function sanitize ($link, $entry) {
}
Reason is without passing it as a parameter, the $link variable becomes undefined. If you had error reporting on, you would have gotten a notice on $link.
For future purposes, whenever in development environment, always turn on error reporting as
error_reporting(E_ALL);//place this at the top of the script
EDIT
In order for you to display the success message and perform a redirect, you'd be better off using Ajax.
setTimeOut();//use this to display the success message for a while(pass number of seconds)
Then perform a redirect using javascript as
window.location.href ='URL';
Using your approach, just declare the success variable as
$success = '';//add this before you use the variable
I've been working on websites for a while now and I keep running into this issue with my contact forms.
So I make sure that I include the "required" on contact forms, and if the form isn't filled out, it's great. It makes sure that the user puts information into the fields for the information to be sent.
However, on iOS that is not the case. Those required tags get ignored, so I constructed my PHP to ensure that the inputs were still required.
Hopefully someone can help me out.
Here is the HTML contact form:
<input type="text" name="phone" class="phoneInput" autocomplete="off" placeholder="What phone number can we reach you at? (Optional)" /><br />
<input type="email" name="email" class="emailInput" autocomplete="off" placeholder="What is your primary e-mail address?" required /><br />
<textarea name="message" id="message" autocomplete="off" placeholder="How may we assist you?" required></textarea><br />
<div class="submit">
<input type="submit" value="SEND MESSAGE" id="button"/>
<div class="ease"></div>
</div>
</form>
updated PHP:
<?php
// Name of sender
$name=$_GET["name"];
// Phone number of sender
$number=$_GET["phone"];
// Mail of sender
$mail_from=$_GET["email"];
// Message
$message=$_GET["message"];
// Subject
$subject= "Someone has sent you a message from your contact form!";
// Message Headers
$headers = 'From: ' .$name."\r\n". 'Reply-To: ' . $mail_from."\r\n" . 'Callback Number: '.$number."\r\n";
// E-mail to:
$to ='shawn#synergycomposites.net';
// Empty variables, tests to see if any of the fields are empty
$emptyName = empty($name);
$emptyEmail = empty($mail_from);
$emptyMessage = empty($message);
// Perform if tests to see if any of the fields are empty, and redirect accordingly
if ($emptyName == true) {
header ("location:/#modalFailure");
} else {
if ($emptyEmail == true) {
header ("location:/#modalFailure");
} else {
if ($emptyMessage == true) {
header ("location:/#modalFailure");
} else {
header ("location:/#modalSuccess");
mail($to, $subject ,$message, $headers);
}
}
}
?>
Your calling the mail() function before checking the fields. This function actually sends the email. The return variable $send_contact is just a Boolean whether the function succeeded or not. Something like this should work:
if(empty($name) || empty($mail_from) || empty($message)) {
header('location:/#modalFailure');
} else {
$mail_sent = mail($to, $subject ,$message, $headers);
if(!$mail_sent) {
header("location:/#modalFailure");
} else {
header("location:/#modalSuccess");
}
}
This code will run into issues if the form submits non-empty strings. For instance this " " instead of "" or NULL. It would also be advisable to add filtering and validation to this code.
( on another note you may want to use $_POST instead of $_GET for form submissions.)
HTML Code
<div id="fourmstyle" class="fourm">
<form action="scripts/mail.php" method="post">
<label for="name">Your Name <required>*</required>
</label>
<input type="text" name="Name" id="Name" placeholder="Joe Bloggs">
<label for="email">Your Email <required>*</required>
</label>
<input type="text" name="Email" id="Email" placeholder="Joebloggs#example.com">
<label for="telephone">Telephone
</label>
<input type="text" name="Telephone" id="Telephone">
<label for="type">Type
</label>
<select name="Type">
<option value="Booking" selected>Booking</option>
<option value="B&B">B&B</option>
<option value="Question">Question</option>
<option value="General">General</option>
<option value="Website Feedback">Website Feedback</option>
</select></p>
<label for="messsage">Message <required>*</required>
</label>
<textarea name="Message" id="Message" rows="5" cols="25">
</textarea></p>
<label for="btn"> </label>
<button type="submit" class="button">Submit
</button>
<br> <requireddescription> *(indicates that the information is required)
</requireddescription>
</form>
PHP Code
<?php
if(isset($_POST))
{
$name = (isset($_POST['Name'])) ? strip_tags($_POST['Name']) : NULL; //if name is set, strip html tags, and return it, otherwise set the string as NULL.
$email = (isset($_POST['Email'])) ? strip_tags($_POST['Email']) : NULL; //same as above.
$telephone = (isset($_POST['Telephone'])) ? preg_replace('~[^0-9\-]~','',$_POST['Telephone']) : NULL; //if telephone is set, remove any characters that are not a number, or a dash, othewise set as NULL.
$type = (isset($_POST['Type'])) ? strip_tags($_POST['Type']) : NULL; //strip tags.
$message = (isset($_POST['Message'])) ? strip_tags($_POST['Message']) : NULL; //strip tags.
if(empty($name) || empty($email) || empty($message))
{
//name, email, and message are required fields, if they are empty, tell the user to go back and fill them in.
echo '<script type="text/javascript"> alert ("Please go back and fill in all required lines"); </script>';
}
else
{
//if the fields are NOT empty, proceed with the mailing.
$formcontent=" From: $name \n Type: $type \n\n Message: $message \n\n Telephone: $telephone";
$recipient = "joebloggs#example.com";
$subject = "Website Contact Form: $type";
$mailheader = "From: $email \r\n";
if(mail($recipient, $subject, $formcontent, $mailheader))
{
//if mail is sent to the SMTP server successfully, echo 'thank you'.
echo '<script type="text/javascript"> alert ("Thankyou '.$name.' we have submitted your message and we will get back to you as soon as possible, if you need to speak to us in the mean time please call 01983 872244 "); </script>';
}
else
{
//otherwise, tell the user it did not go through.
echo '<script type="text/javascript"> alert ("I am sorry but there has been an error submitting your request please try again or call us on 01983 872244"); </script>';
}
}
}
?>
Ok so my code above works quite nicely and I have JS pop up alerts. However, when I ok the JS alert it takes me back to the mail.php script and not the HTML page in which it originated from how would I rectify this ?
This should help solve your immediate issue... but in the future, try out an AJAX call.
if(mail($recipient, $subject, $formcontent, $mailheader))
{
//if mail is sent to the SMTP server successfully, echo 'thank you' and return to previous page.
echo '<script type="text/javascript"> alert ("Thankyou '.$name.' we have submitted your message and we will get back to you as soon as possible, if you need to speak to us in the mean time please call 01983 872244 "); window.history.back(); </script>';
}
else
{
//otherwise, tell the user it did not go through.
echo '<script type="text/javascript"> alert ("I am sorry but there has been an error submitting your request please try again or call us on 01983 872244"); window.history.back(); </script>';
}
EDIT
forgot to include the first instance
if(empty($name) || empty($email) || empty($message))
{
//name, email, and message are required fields, if they are empty, tell the user to go back and fill them in and send them back.
echo '<script type="text/javascript"> alert ("Please go back and fill in all required lines"); window.history.back()</script>';
}
When you submit to mail.php, mail.php becomes the new page your user is on. If you want them to still be on the page from which they called it, you either need to submit it via AJAX, or tell the browser to go back to the page from which the script was called. To do it the second way, add this to your script echos:
window.history.back()
It depends on what you've done in your HTML page:
If your PHP was called via ajax, then you need to add return false to the javascript function that initiated that ajax call.
If you have a form and the form's submission via regular postback to the action's url was how you processed that PHP page, then you need to either add a redirect in PHP back to that page WHILE storing that alert message in session so it doesn't get lost, OR throw some HTML after that PHP.