0

I have made a form that emails the info entered in the fields but I am getting an error when filled out.

Could not send mail! Please check your PHP mail configuration.

All the code seems good but I can't find the cause of the error. The error shows once I try to submit the form (which is the error message meant to show on a send mail error). Any help is greatly appreciated!!

I should mention that there are 2 forms in the directory; Form "1", uses the "1" versions of the JS and PHP files, Form "2' uses the "2" version. They do not share the JS and PHP files.

<form id="email-form2" name="email-form2" method="POST" data-name="Insurance Form">
  Enter Name
  <input class="w-input text-field" id="name" type="text" placeholder="First name and last name" name="name" data-name="Name" required> Email
  <input class="w-input text-field" id="email" type="email" name="email" placeholder="Enter your email address" data-name="Email" required> Date of Birth
  <input class="w-input text-field" id="date" type="date" name="date" data-name="Date" required> Gender
  <input class="w-input text-field" id="gender" type="text" placeholder="Male or Female" name="gender" data-name="Gender" required> Member ID
  <input class="w-input text-field" id="member" type="text" placeholder="Member number" name="member" data-name="Member" required> Policy ID
  <input class="w-input text-field" id="policy" type="text" placeholder="Policy number" name="policy" data-name="Policy" required>
  <div class="div-spc">
    <button class="w-button button no-margin" type="submit">Submit Form</button>
  </div>
</form>
<?php
  if($_POST) 
  {
    $to_Email = "email@email.com"; //Replace with recipient email address

    //check if its an ajax request, exit if not
    if (!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') 
    {   
      //exit script outputting json data
      $output = json_encode(array(
        'type'=> 'error',
        'text' => 'Request must come from Ajax'
      ));

      die($output);
  }

  //check $_POST vars are set, exit if any missing
  if (!isset($_POST["userName"]) || !isset($_POST["userEmail"]) || !isset($_POST["userDate"]) || !isset($_POST["userGender"]) || !isset($_POST["userMember"]) || !isset($_POST["userPolicy"])) 
  {
    $output = json_encode(array('type'=>'error', 'text' => 'Input fields are empty!'));
    die($output);
  }

  //additional php validation
  if (empty($_POST["userName"])) 
  {
    $output = json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!'));
    die($output);
  }

  if (!filter_var($_POST["userEmail"], FILTER_VALIDATE_EMAIL)) 
  {
    $output = json_encode(array('type'=>'error', 'text' => 'Please enter a valid email!'));
    die($output);
  }

  if (empty($_POST["userMember"])) 
  {  
    $output = json_encode(array('type'=>'error', 'text' => 'Need Member ID number!'));
    die($output);
  }

  if (empty($_POST["userGender"])) 
  {
    $output = json_encode(array('type'=>'error', 'text' => 'Please enter Male or Female!'));
    die($output);
  }
  if (empty($_POST["userPolicy"])) 
  {
    $output = json_encode(array('type'=>'error', 'text' => 'Need Policy ID number!'));
    die($output);
  }

  if (empty($_POST["userDate"])) 
  {
    $output = json_encode(array('type'=>'error', 'text' => 'Please fill out birth date!'));
    die($output);
  }

  //proceed with PHP email.
  $headers = 'From: '.$_POST["userEmail"].'' . "\r\n" .
    'Reply-To: '.$_POST["userEmail"].'' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

  // send mail
  $sentMail = @mail($to_Email, $_POST["userName"], $_POST["userDate"], $_POST["userGender"], $_POST["userMember"], $_POST["userPolicy"], $headers);

  if (!$sentMail) 
  {
    $output = json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.'));
    die($output);
  } else {
    $output = json_encode(array('type'=>'message', 'text' => 'Hi '.$_POST["userName"] .' Thank you for your email'));
    die($output);
  }
}
?>
$(document).on("ready", function() {
  $("#email-form2 [type='submit']").click(function(event) {
    event.preventDefault();
    //get input field values
    var user_name = $('input[name=name]').val()
    var user_email = $('input[name=email]').val()
    var user_date = $('input[name=date]').val()
    var user_gender = $('input[name=gender]').val()
    var user_member = $('input[name=member]').val()
    var user_policy = $('input[name=policy]').val()

    //data to be sent to server
    post_data = {
      'userName': user_name,
      'userEmail': user_email,
      'userGender': user_gender,
      'userMember': user_member,
      'userPolicy': user_policy,
      'userDate': user_date
    }

    //Ajax post data to server
    $.post('contact_me2.php', post_data, function(response) {
      //load json data from server and output message    
      if (response.type == 'error') {
        output = '<div class="error-message"><p class="from">' + response.text + '</p></div>'
      } else {
        output = '<div class="success-message"><p class="seuccses">' + response.text + '</p></div>'

        //reset values in all input fields
        $('#email-form2 input').val('')
      }
      $("#result").hide().html(output).slideDown()
    }, 'json')
  });

  //reset previously set border colors and hide all message on .keyup()
  $("#email-form2 input").keyup(function() {
    $("#result").slideUp()
  })
});
ADyson
  • 57,178
  • 14
  • 51
  • 63
DFC
  • 13
  • 4
  • 1
    Side issue: You know that `if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') { ` is near enough pointless? It might stop a postback from a browser form, but that's about it. Any other HTTP client could just spoof the header and pretend to be an ajax client. – ADyson Mar 29 '19 at 14:06
  • Anyway regarding your issue. You'll see that message if `$sentMail` is false-y. That all seems in order. What you didn't make clear was, is the email actually being delivered in reality? Otherwise I'm not sure what the cause of your confusion is...the code would appear to do what it's supposed to in that situation? – ADyson Mar 29 '19 at 14:08
  • Turn un PHP error handling and submit the form without any JS. Does it send? – mplungjan Mar 29 '19 at 14:09
  • Another side point: the way you're doing the server-side validation is a bit clunky. Why not check _all_ the validation rules, build up an array of errors, and return all the errors at once? Then the user can fix everything at one go. Otherwise potentially they have to keep re-submitting the form again and again until they clear all of the rules. – ADyson Mar 29 '19 at 14:09
  • Another side point: `$("#email-form2 [type='submit']").click(function(event) {` could be simplified to `$("#email-form2").submit(function(event) {` And then if you make the `name` attributes of your fields match the ones that PHP is looking for in $_POST, you can get rid of all the JS code that manually gets the values from each field (from `var user_name =...` to `var post_data = ...` inclusive), and instead just write `$.post('contact_me2.php', $(this).serialize(), function(response) {` – ADyson Mar 29 '19 at 14:10
  • If it isn't sending the mail, there could be many possible causes (see https://stackoverflow.com/questions/24644436/php-mail-function-doesnt-complete-sending-of-e-mail), but just based on the code, I'd say `'From: '.$_POST["userEmail"].'' . "\r\n"` is a possible cause. – ADyson Mar 29 '19 at 14:18
  • Don't spoof the sender, this can often be flagged as spam. Instead just use a generic "donotreply@yourdomain.com" address which is in the same domain as the mailserver which sends the mail. If the From address is from the same domain as the sending server it's far less likely to look suspicious. The mailserver might not even accept From fields which aren't on its domain. – ADyson Mar 29 '19 at 14:18
  • `@mail($to_Email, $_POST["userName"], $_POST["userDate"], $_POST["userGender"], $_POST["userMember"], $_POST["userPolicy"], $headers);` that is way too many variables for the function. The function definition is `mail ( string $to , string $subject , string $message [, mixed $additional_headers [, string $additional_parameters ]] )` Instead of sending the post variables, you need to create a message string. – aynber Mar 29 '19 at 14:21
  • 1
    The error message says that there might be an error in PHP's mail configuration. You don't say whether you can send mail at all. Right now, you have a lot of code with a bunch of stuff going on. Try writing a test PHP script that simply sends you a test message. If that doesn't work, then check your mail configuration, like the message says. – arensb Mar 29 '19 at 14:22
  • First of all, thank you so much to all who responded! I need to clarify that I am NOT a coder and my knowledge of even HTML/CSS is basic at best. ADyson: the emails are not being delivered, I only get the error message. The fields also don't clear, as is intended upon submission of the form. Your server-side validation suggestion is great, though, but I wouldn't know how to compact that. – DFC Mar 29 '19 at 14:23
  • aynber: Yes, the only difference is it seems in that situation that the code goes through fine but the email never does. In my case, I keep getting the error so the form is never really submitted, fields don't clear, I don't get the "thank you" message, etc – DFC Mar 29 '19 at 14:29
  • 1
    Of course not, your email is never being sent. You're only attempting to clear the fields if the response.type is not error. You said you receive the message `Could not send mail! Please check your PHP mail configuration.`, which is what you have configured to show when the mail is not sent successfully. `mail()` throws an error because you're not sending it correctly. – aynber Mar 29 '19 at 14:32
  • I also need to mention that the JS and PHP are based on another JS and PHP used in the same website, for the Contact form, and they work perfectly well. The things I changed were adding all the new or different variables for the new form but all that PHP mail info is all the same – DFC Mar 29 '19 at 14:33
  • @DFC I just noticed something. Take a look at the [documentation for mail()](https://www.php.net/manual/en/function.mail.php). How many parameters does the function accept? (answer: 5). Now, how many parameters are you sending it in your code? (answer: 7). Can you see how that might be a problem? Also you're using `@` at the start of `mail()` which will suppress any errors which might have been thrown as a result. Even if it doesn't error, you're sending it nonsensical data for everything after the $message parameter, and that's why it's not working. – ADyson Mar 29 '19 at 14:44
  • @DFC ..cont'd. I expect perhaps you really want to join all those various fields (username, gender, date, policy, etc) together in a single string, so that it forms a coherent message body, rather than just firing them at the mail() function and hoping it rearranges them into something readable (which, to be clear, it can't and won't). – ADyson Mar 29 '19 at 14:45
  • ADyson: So how would I go about grouping those parameters so the field information appears in the email? All I need to email to show is Name, Email, DoB, Gender, Member ID, Policy ID when the other party receives it. – DFC Mar 29 '19 at 14:57
  • Again, I need to clarify I need to be led through this by hand. I know nothing of JS and/or PHP so I literally need the answer (or possible answer) written out. I apologize for my limited -to-non-existent knowledge of coding (I'm a brand/graphic designer). – DFC Mar 29 '19 at 15:02
  • This gives you the basic idea how to combine them: https://www.geeksforgeeks.org/concatenation-two-string-php/ . You probably want to put some things in between them like spaces / newlines etc as well to aid presentation. But to give you a start, try this: `$sentMail = mail($to_Email, "Some subject", $_POST["userName"]." ".$_POST["userDate"]." ". $_POST["userGender"]." ".$_POST["userMember"]." ".$_POST["userPolicy"], $headers);` This will put all the fields into the message, separated by spaces. You can add more content yourself inside the double-quoted areas. – ADyson Mar 29 '19 at 15:03
  • 2
    P.S. Why are you being asked to code a web form if you ain't a coder? Not that you can't learn of course, but maybe if you're serious about doing it you should take some tutorials and learn the basics before diving into something you stand no chance of actually achieving (or of understanding the end result, if we help you with it) – ADyson Mar 29 '19 at 15:04
  • Yes! Absolutely. I will definitely hit the books and tutorials. I'm an artist but I can always use a much more expanded set of tools and brushes... – DFC Mar 29 '19 at 15:14
  • Um, your code suggestion worked, ADyson... I owe you a beer or lunch or something, lol. – DFC Mar 29 '19 at 15:22
  • Thank you to everyone else as well! Much appreciated. – DFC Mar 29 '19 at 15:31
  • @DFC no problem, glad it helped you. Beer is nice but hard to deliver through a website, so some reputation points will do just fine, thanks! I've written up the solution as a proper Answer below, so if you could mark it as "accepted" (click the tick mark next to the answer so it turns green), I'd be grateful (and so would other readers who come to this question with a similar issue in future). Thanks :-). P.S. good luck in your future programming projects! – ADyson Mar 29 '19 at 16:04

1 Answers1

0

If you take a look at the documentation for mail(), you'll see that the function accepts 5 parameters.

Now, how many parameters are you sending it in your code? (answer: 7). Can you see how that might be a problem? Also you're using @ at the start of mail() which will suppress any errors which might have been thrown as a result.

Even if it doesn't error, you're sending it nonsensical data for everything after the $message parameter, and that's why it's not working. I expect perhaps you really want to join all those various fields (username, gender, date, policy, etc) together in a single string, with some formatting such as spaces and newlines etc, so that it forms a coherent message body - rather than just firing them all at the mail() function and hoping it rearranges them into something readable (which, to be clear, it can't and won't).

To give you a start, try this:

$subject = "Some subject";
$message = $_POST["userName"]." ".$_POST["userDate"]." ". $_POST["userGender"]." ".$_POST["userMember"]." ".$_POST["userPolicy"];
$sentMail = mail($to_Email, $subject, $message, $headers); 

Here I have

a) declared the subject and message as separate variables, to improve clarity and readability.

b) joined the various POST field values together into a single string, separated by spaces. In PHP, joining strings (also called "concatenation") is done using the . operator - you simple place it in between two strings that you want to join to each other.

You can add more content yourself inside the double-quoted areas, and change the subject line to your liking.

ADyson
  • 57,178
  • 14
  • 51
  • 63
  • I have one final request for help! Everything exactly the same as above except the "Gender" field is now a dropdown menu with "Male" and "Female" options. I need to know how to get the value, previously: var user_gender = $('input[name=gender]').val() – DFC Apr 06 '19 at 14:51
  • Since the input (text box) is now a select (drop-down) then try $('select[name=gender]').val() – ADyson Apr 06 '19 at 18:12