Search code examples
phphtmlvalidationphpmailercontact-form

Why these input validations are not working? (contact us form via PHP & HTML & SMTP server & PHPmailer)


I'm using PHP & HTML & SMTP server & PHPmailer to create a contact us form with user input validation. But after pressing "submit" button it gives me an error:

Invalid address: (From): Fatal error: Uncaught PHPMailer\PHPMailer\Exception: Invalid address: (From): in C:\xampp\htdocs\RESPONSIVE SITE3_2\vendor\phpmailer\phpmailer\src\PHPMailer.php:1324 Stack trace: #0 C:\xampp\htdocs\RESPONSIVE SITE3_2\send-email.php(74): PHPMailer\PHPMailer\PHPMailer->setFrom('', '') #1 {main} thrown in C:\xampp\htdocs\RESPONSIVE SITE3_2\vendor\phpmailer\phpmailer\src\PHPMailer.php on line 1324

PHP code:

<?php

$name = $_POST["name"];
$email = $_POST["email"];
// $email = test_input($_POST["email"]);
$message = $_POST["message"];

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $emailErr = "Invalid email format";
} 

if (!preg_match("/^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+$/", $email)) {
    $emailErr = "Email should contain only letters, numbers, and underscores";
}

require "vendor/autoload.php";

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;

$mail = new PHPMailer(true);

$mail->SMTPDebug = SMTP::DEBUG_SERVER;

$mail->isSMTP();
$mail->SMTPAuth = true;

$mail->Host = "smtp.gmail.com";
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;

require_once 'config.php';
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;

$mail->setFrom($email, $name);
$mail->addAddress("[email protected]", "Ads");

$mail->Subject = $subject;
$mail->Body =  "Name: $name\nEmail: $email\n\n$message";

$mail->send();

header("Location: sent.html");
?>

HTML code

<form method="POST" action="send-email.php">
    <input type="text" name="name" id="name" placeholder="Name*">
    
    <input type="email" name="email" id="email" placeholder="Email*">
    <span class="error" style="color:red"><?php echo $emailErr;?></span>

    
    <textarea name="message" id="message" placeholder="Your Message*"></textarea>
    
    <button type="submit" name="submit" id="submit" class="button">Start</button>
</form>

I was trying different tutorials - unsuccessful. I need this form to

  • validate user input and only numbers and letters are allowed to insert (mail field)
  • if data is not valid error message must appear under the input field

I'm a very new to this, please explain in very simple words :)


Solution

  • Diagnosis

    If either of the validation if statements are true, all that will happen is it sets a string variable $emailErr.

    Then the code exits the if block again, and the script just carries on its merry way and tries to send the email anyway. There is no logic in the code which prevents this.

    And at the end of that, $emailErr never gets used because the code is redirecting the user to a different HTML page which cannot involve that variable.

    Solution

    You need some extra logic to tell the code to skip the email-sending part if any of the validations failed. One way to achieve this neatly is quite easy, using a "flag" variable.

    For example:

    <?php
    require "vendor/autoload.php";
    
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    
    $name = $_POST["name"];
    $email = $_POST["email"];
    // $email = test_input($_POST["email"]);
    $message = $_POST["message"];
    $valid = true;
    $emailErr = "";
    
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $emailErr = "Invalid email format";
        $valid = false;
    } 
    
    if (!preg_match("/^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+$/", $email)) {
        $emailErr = "Email should contain only letters, numbers, and underscores";
        $valid = false;
    }
    
    //only send if all validations passed:
    if ($valid == true)
    {
      $mail = new PHPMailer(true);
    
      $mail->SMTPDebug = SMTP::DEBUG_SERVER;
    
      $mail->isSMTP();
      $mail->SMTPAuth = true;
    
      $mail->Host = "smtp.gmail.com";
      $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
      $mail->Port = 587;
    
      require_once 'config.php';
      $mail->Username = SMTP_USERNAME;
      $mail->Password = SMTP_PASSWORD;
    
      $mail->setFrom($email, $name);
      $mail->addAddress("[email protected]", "Ads");
    
      $mail->Subject = $subject;
      $mail->Body =  "Name: $name\nEmail: $email\n\n$message";
      $mail->send();
    
      header("Location: sent.html");
    }
    else
    {
      echo $emailErr;
    }
    

    P.S. As an aside, your regular expression is too restrictive - see What characters are allowed in an email address? . And since you're using FILTER_VALIDATE_EMAIL already, you shouldn't really need it in any case.