Contact form sends blank emails from time to time


#1

Hi, guys. Along with ‘normal’ emails my html+php contact form sends blank messages to the inbox. Thought the prob was with lack of condition for ‘not sending a message, unless the fields are filled in’, but, in fact, the condition is in place. Could you briefly look through the code and kindly suggest any corrections, so I get rid of numerous blank emails (btw, I’m not that good at html and php, so hope your advice helps). Thanks in advance, would be of much help!

My html code:

					<div class="col-lg-6 mt-30">
						<form id="myForm" action="mail.php" method="post" class="contact-form">
							<div class="single-input color-2 mb-10">
								<input type="text" name="fname" placeholder="Имя Фамилия" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Имя Фамилия'" required>
							</div>
							<div class="single-input color-2 mb-10">
								<input type="email" name="email" placeholder="Ваш email" pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{1,63}$" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Ваш email'" required>
							</div>
							<div class="single-input color-2 mb-10">
								<input type="text" name="subject" placeholder="Тема" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Тема'" required>
							</div>

							<div class="single-input color-2 mb-10">
								<textarea name="message" placeholder="Введите ваше сообщение..." onfocus="this.placeholder = ''" onblur="this.placeholder = 'Введите ваше сообщение...'" required></textarea>
							</div>
							<div class="d-flex justify-content-end"><button class="mt-10 primary-btn d-inline-flex text-uppercase align-items-center">Отправить<span class="lnr lnr-arrow-right"></span></button></div>
							<div class="alert"></div>
						</form>
					</div>

My php code:

<?php
    $to = 'info@example.ru';
    $firstname = $_POST["fname"];
    $subject= $_POST["subject"];
    $email= $_POST["email"];
    $text= $_POST["message"];
    


    $headers = 'MIME-Version: 1.0' . "\r\n";
    $headers .= "From: " . $email . "\r\n"; // Sender's E-mail
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

    $message ='<table style="width:100%">
        <tr>
            <td>'.$firstname.'  '.$laststname.'</td>
        </tr>
        <tr><td>Subject: '.$subject.'</td></tr>
        <tr><td>Email: '.$email.'</td></tr>
        <tr><td>Email: '.$text.'</td></tr>
        
    </table>';

    if (@mail($to, $email, $message, $headers))
    {
        echo 'Сообщение отправлено.';
    }else{
        echo 'failed';
    }

?>


#2

Do the same check in your PHP code. Make sure all fields have a value before you fire the mail() command.

What’s likely happening is a semi-careless search bot is crawling your website, seeing a form pointing to a URL, and going to that URL without actually sending form data.


#3

@alexanderrostov61 . I think @m_hutley is absolutelly right. What you should do first is checking if it is a post request:

if ($_SERVER["REQUEST_METHOD"] == "POST")

if it is not a post request. Redirect them back to the page holding the form:

header("Location: http://www.yoursite.com/");
exit;

if it is a post request you should check if the fields have a value:

if (empty($fname) OR empty($email) OR empty($subject) OR empty($message))

if one or more fields don’t have a value, as in the code, you can redirect back to the page holding the form:

header("Location: http://www.yoursite.com/");
exit;

When all fields have a value and it is a post request, only then fire the mail function

Edit: Next to the redirect you could have messageg as well. Stating what went wrong incase it is/was not a search bot


#4

Actually, the “condition” (required) is in place for “your” form. Nothing says a POST request has to come from your form. As pointed out, you need to validate the required fields in your processing code.

One thing that was not mentioned is that you need to TRIM the POST array before the checks. Blank spaces will bypass an empty check.


#5

Furthermore, you may use as per the following code, to check empty condition, to trim the POST array and to stripslaces POST array as well as htmlspecialchars().

<?php
// define variables and set to empty values
$nameErr = $emailErr = $genderErr = $websiteErr = "";
$name = $email = $gender = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
  if (empty($_POST["name"])) {
    $nameErr = "Name is required";
  } else {
    $name = test_input($_POST["name"]);
  }
  
  if (empty($_POST["email"])) {
    $emailErr = "Email is required";
  } else {
    $email = test_input($_POST["email"]);
  }
    
  if (empty($_POST["website"])) {
    $website = "";
  } else {
    $website = test_input($_POST["website"]);
  }

  if (empty($_POST["comment"])) {
    $comment = "";
  } else {
    $comment = test_input($_POST["comment"]);
  }

  if (empty($_POST["gender"])) {
    $genderErr = "Gender is required";
  } else {
    $gender = test_input($_POST["gender"]);
  }
}

function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}
?>

The htmlspecialchars() function converts special characters to HTML entities. This means that it will replace HTML characters like < and > with &lt; and &gt;


split this topic #6

A post was split to a new topic: Contact form is sending only empty emails


#7

@iflameinstitute, That code is just all kinds of wrong. Since it is pretty much every line I am not going to get into every problem. Perhaps someone else will.


#8

Wow, that’s rather harsh, @benanamen!

While I would do some of the steps differently / use some different naming, the overall flow of the code is not “all kinds of wrong”, in terms of the end result it achieves.

Please elaborate on what you find wrong with it, otherwise your post is just trolling.


#9

Telling the truth about CODE is not harsh.

In any case, lets start with the first 75%. The CODE sets TWO strings of completely unnecessary strung together empty strings of variables, one of which doesn’t even exist in the code. ($websiteErr). Then it goes through blocks of empty checks without trimming the post array even though it is mentioned in the post which which will completely fail when spaces are entered. Then if the POST’ed fields are actually empty errors, variables are set that do absolutely nothing and should actually be put into an array anyways. Then the entire REQUEST_METHOD block doesn’t go anywhere whatsoever. Then the incorrectly named test_input function is obviously grabbed from a 1990s database output function that is just floating around unused.

The only thing right about the CODE is the check for the REQUEST_METHOD. So like I said, just about every line. With all that, it does qualify as “all kinds of wrong”.


#10

Indeed it’s not, but that’s not what you were doing. You were calling the code “all kinds of wrong” without bothering to explain why. That really doesn’t help anyone. People who know what you mean will know, but people who aren’t that versed in PHP will be left confused and probably annoyed.

So it’s not about what you said, it’s about how you said it.

Regarding your comments, the setting of variables at the beginning of the script is you can refer to any of those variables after the if block without using isset all the time, because you’re know they’re defined with an empty value by default. The $websiteErr is indeed not that nice, but I’ve seen worse things.
Personally I’d create an array $errors and push any new errors in that array, but this should work too.

trimming of values before checking is good, but notice that the OP never made such a request, you added that.

I agree that checking for REQUEST_METHOD would be better.


#11

I agree. At the time I was on my phone and not inclined to get into details at the time.

My reply was not to the OP, it was directly to the one that posted that code who did in fact mention it.

That’s the thing, There isn’t anything after the if blocks in the posted code which I pointed out. I realize the code is supposed to be a partial example but it will only cause confusion to those that don’t know better.