This question already has answers here:
PHP mail function doesn't complete sending of e-mail
(31 answers)
Closed 5 years ago.
I have an event that fires every time a user successfully submits a form on my website. I can track the exact time that the event fired from my Google Analytics account. The time that the event fired, mirrors the delivery time of the email delivered to my inbox (yahoo mail).
However, I've noticed many times that, when the same event fires, no email is delivered to the the same email address. It never reaches its destination.
How can I fix this? What is the root of this problem?
Here is my php code:
<?php
if($_POST)
{
//check if its an ajax request, exit if not
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
die();
}
//check $_POST vars are set, exit if any missing
if(!isset($_POST["userName"]) || !isset($_POST["userLastName"]) || !isset($_POST["userEmail"]) || !isset($_POST["userArrival"]) || !isset($_POST["userNumberPeople"])
|| !isset($_POST["userPickupLocation"]) || !isset($_POST["userRequest"]) || !isset($_POST["userTourSelection"]))
{
die();
}
//Sanitize input data using PHP filter_var().
$user_Name = filter_var($_POST["userName"], FILTER_SANITIZE_STRING);
$user_LastName = filter_var($_POST["userLastName"], FILTER_SANITIZE_STRING);
$user_Email = filter_var($_POST["userEmail"], FILTER_SANITIZE_EMAIL);
$user_TourSelection = filter_var($_POST["userTourSelection"], FILTER_SANITIZE_STRING);
$user_Arrival = filter_var($_POST["userArrival"], FILTER_SANITIZE_STRING);
$user_NumberPeople = filter_var($_POST["userNumberPeople"], FILTER_SANITIZE_STRING);
$user_PickupLocation = filter_var($_POST["userPickupLocation"], FILTER_SANITIZE_STRING);
$user_Request = filter_var($_POST["userRequest"], FILTER_SANITIZE_STRING);
$to_Email = "something#yahoo.com"; //Replace with recipient email address
$subject = 'Tour request: '.$user_TourSelection.' '; //Subject line for emails
//additional php validation
if(strlen($user_Name)<2) // If length is less than 4 it will throw an HTTP error.
{
header('HTTP/1.1 500 Name is too short or empty!');
exit();
}
if(!filter_var($user_Email, FILTER_VALIDATE_EMAIL)) //email validation
{
header('HTTP/1.1 500 Please enter a valid email address!');
exit();
}
if(strlen($user_Request)<5) //check emtpy message
{
header('HTTP/1.1 500 Please explain in a few words how you would like us to assist you.');
exit();
}
// message
$message = '<strong>Name:</strong> '.$user_Name.' '.$user_LastName.' <br><br>
<strong>Date of Arrival:</strong> '.$user_Arrival.' <br><br>
<strong>Tour:</strong> '.$user_TourSelection.' <br><br>
<strong>Number of people:</strong> '.$user_NumberPeople.' <br><br>
<strong>Pick-Up Location:</strong> '.$user_PickupLocation.' <br><br>
<strong>Request:</strong> '.$user_Request.'
';
//proceed with PHP email.
$headers = 'From: '.$user_Email.'' . "\r\n" .
$headers .='Reply-To: '.$user_Email.'' . "\r\n" ;
$headers .= 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .='X-Mailer: PHP/' . phpversion();
#$sentMail = mail($to_Email, $subject, $message, $headers);
if(!$sentMail)
{
header('HTTP/1.1 500 Our server is under maintenance!<br> If this error persists please contact us directly: <strong>something#yahoo.com</strong>');
exit();
}else{
echo 'Congratulations '.$user_Name .'! ';
echo 'We have received your request and we will respond as soon as possible.';
}
}
?>
mail()'s delivery function ends when it hands off your mail to the SMTP server. Its sole responsibility is the real-world equivalent of taking your envelope and dropping it into the mailbox on the corner. The rest of the postal service (emptying that box, running it through processing centers, flying it to the recipient's country/city, etc...) is completely outside of mail()'s scope. As long as the envelope drops into the mailbox, mail() will return true and pretend it was delivered.
So... check your SMTP server's logs to see what really happened to the mail. Maybe it got marked as spam by the receiver and bounced. Maybe it's stuck in a queue somewhere, etc... Only the logs will tell you this - anything you can see/do in PHP is useless, because PHP and mail() only do maybe 1% of the email sending/delivery process, and something's wrong in that other 99%.
Related
I am trying to send email from a web page hosted on a shared platform over at fasthosts. I cannot for the life of me get this to work, I had a much more extensive script which checked the validity of email etc, but now I've been reduced to using the basic example from fasthosts and it is still not working.
Please could someone take a look and let me now where I am going wrong...
<?php
// You only need to modify the following two lines of code to customise your form to mail script.
$email_to = "contact#mywebsite.co.uk"; // Specify the email address you want to send the mail to.
$email_subject = "Feedback from website"; // Set the subject of your email.
// This is the important ini_set command which sets the sendmail_from address, without this the email won't send.
ini_set("contact#mywebsite", $email_from);
// Get the details the user entered into the form
$name = $_POST["name"];
$email = $_POST["email"];
$message = $_POST["message"];
// Validate the email address entered by the user
if(!filter_var($email_from, FILTER_VALIDATE_EMAIL)) {
// Invalid email address
die("The email address entered is invalid.");
}
// The code below creates the email headers, so the email appears to be from the email address filled out in the previous form.
// NOTE: The \r\n is the code to use a new line.
$headers = "From: " . $email_from . "\r\n";
$headers .= "Reply-To: " . $email_from . "\r\n"; // (You can change the reply email address here if you want to.)
// Now we can construct the email body which will contain the name and message entered by the user
$message = "Name: ". $name . "\r\nEmail: " . $email . "\r\nMessage: " . $message ;
// Now we can send the mail we've constructed using the mail() function.
// NOTE: You must use the "-f" parameter on Fasthosts' system, without this the email won't send.
$sent = mail($email_to, $email_subject, $message, $headers, "-f" . $email_from);
// If the mail() function above successfully sent the mail, $sent will be true.
if($sent) {
$output = json_encode(array('type'=>'message', 'text' => 'Hi '.$name .' Thank you for contacting us.'));
die($output);
} else {
$output = json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.'));
die($output);
}
?>
I'm having an issue with a contact form. The email message is correctly sent but in my inbox appears as "From: anonymous#web.godns.net" and not "From: web#mywebsite.com", and goes directly to SPAM.
I've been looking for similar issues but no one gives the specific answer. I guess if the code is having a syntax mistake or it's a server problem.
This is the PHP file:
<?php
// Check for empty fields
if(empty($_POST['name']) || empty($_POST['email']) || empty($_POST['phone']) || empty($_POST['message']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
http_response_code(500);
exit();
}
$name = strip_tags(htmlspecialchars($_POST['name']));
$email = strip_tags(htmlspecialchars($_POST['email']));
$phone = strip_tags(htmlspecialchars($_POST['phone']));
$message = strip_tags(htmlspecialchars($_POST['message']));
// Create the email and send the message
$to = "myemail#gmail.com";
$subject = "Mensaje Web de >> $name";
$body = "Recibiste mensaje a través del formulario en la web.\n"."Estos son los datos:\n\nNombre y Apellido: $name\n\nEmail: $email\n\nTeléfono: $phone\n\nTexto del mensaje:\n$message";
$headers= "From: web#mywebsite.com" . "\r\n" .
"Reply-To: $email \r\n" .
'X-Mailer: PHP/' . phpversion();
if(!mail($to, $subject, $body, $headers))
http_response_code(500);
?>
Does anyone figure out what's wrong here?
Thank you,
Alejandra | aleare.design
It may solve your problem or not but it's always a good idea to set a proper sender address. In good old mail() that needs to be done with the $additional_parameters parameter and the syntax is -f followed by an email address with no display name:
mail($to, $subject, $body, $headers, '-fweb#mywebsite.com')
Additionally, make sure that your local SMTP server allows sending messages in the name of web#mywebsite.com. If it doesn't, perhaps you need to get another server and make use of authentication, something that mail() doesn't allow.
In any case, it's really hard to get email right with this function since you need to do everything by yourself and email protocol is not trivial. For instance, I think your code is vulnerable to email headers injection. It's easier to just use a third-party library like Swift Mailer or PHPMailer.
P.S. What are you trying to accomplish with strip_tags(htmlspecialchars())? This will just make user input unreadable for not obvious gain.
This might help you, I don't get it why you put so many text in the header
// Create the email and send the message
$to = "youremail#yourdomain.com"; // Add your email address inbetween the " " replacing username#yourdomain.com - This is where the form will send a message to.
$subject = "Website Contact Form: $name";
$body = "You have received a new message from your website contact form.\n\n"."Here are the details:\n\nName: $name\n\nEmail: $email\n\nPhone: $phone\n\nMessage:\n$message";
$header = "From: noreply#adamar.com\n"; // This is the email address the generated message will be from. We recommend using something like noreply#yourdomain.com.
$header .= "Reply-To: $email"; // this is to automatically reply to your correspondent email rather than your noreply email, I separate it from your header.
also mind to change the variable $headers to $header? Maybe it might help. Wish all the best of it. Cheers!
I am using PHPMailer to send automated e-mails from my website and while testing, I noticed that when I sent mail from website by Gmail, then e-mails sent by php mailer are generating the following warning on the recipients end:
This message may not have been sent by: example#gmail.com Learn more Report phishing.
But when I use other emails (like yahoo, outlook), then I got no emails in my $contact_email. Please help me to solve this problem.
PHP Mailer code:
<?php
global $_REQUEST;
$response = array('error'=>'');
$user_name = substr($_REQUEST['user_name'], 0, 20);
$user_email = substr($_REQUEST['user_email'], 0, 40);
$user_msg = $_REQUEST['user_msg'];
$contact_email = 'contact.arefin#gmail.com';
if (trim($contact_email)!='') {
$subj = 'Message from Official Website';
$msg = "Name: $user_name
E-mail: $user_email
Message: $user_msg";
$head = "Content-Type: text/plain; charset=\"utf-8\"\n"
. "X-Mailer: PHP/" . phpversion() . "\n"
. "Reply-To: $user_email\n"
. "To: $contact_email\n"
. "From: $user_email\n";
if (!#mail($contact_email, $subj, $msg, $head)) {
$response['error'] = 'Error send message!';
}
} else
$response['error'] = 'Error send message!';
echo json_encode($response);
die();
?>
When you send bulk emails and especially when you mock the sender address, you need to use best practices that may reduce how many servers block you as spammer.
Three things which I think you should do are:
1) Use appropriate mail headers
Add the following to your code - a notice that this is a bulk sender, and the OPT-OUT email address:
.= "X-mailer: YOUR_SITE_DOMAIN Server" . "\r\n"; // this will identify the real sender
.= "Precedence: bulk" . "\r\n"; // this will say it is bulk sender
.= "List-Unsubscribe:info#YOUR_SITE_DOMAIN\r\n"; // this will reveal the OPT-OUT address
Read more about it here
2) Make sure your server domain has a reverse DNS record. This will tell the recipient's server that your domain is REALLY hosted on your server.
3) Publish SPF record with your domain. You can read more about it here, and google it for other big handlers (like Yahoo).
In addition to those, make sure you are adding a footer with a "one click" OPT-OUT removal option and explanation note that this message is sent on behalf, and who is the original sender.
Cheers
You can either set up google apps for your site and get a Username#yourwebsite.com gmail account (more info: http://www.google.com/enterprise/apps/business/), or You will need to set up an e-mail address on your current server that is Username#yourwebsite.com and use that as the $mail->from address.
Your E-Mail recipients are receiving the message because you are telling google to send an e-mail from your server, and then you are telling them that the mail is coming from gmail, which it isn't, it's coming from your personal server. Since the from address and your server address don't match, they flag it as spam. This is googles way of preventing spam, to them it would be the same if you put $mail->from(YOURMOM#LOL.com). The e-mail would still send, but your domain name does not match the # address.
Try this code , In your code i found some mistake which i have solved here.
global $_REQUEST;
$response = array('error'=>'');
$user_name = substr($_REQUEST['user_name'], 0, 20);
$user_email = substr($_REQUEST['user_email'], 0, 40);
$user_msg = $_REQUEST['user_msg'];
$contact_email = 'contact.arefin#gmail.com';
if (trim($contact_email)!='') {
$subj = 'Message from Official Website';
$msg = "Name: $user_name
E-mail: $user_email
Message: $user_msg";
$head = "Content-Type: text/plain; charset=\"utf-8\"\n"
. "X-Mailer: PHP/" . phpversion() . "\n"
. "Reply-To: $user_email\n"
. "To: $contact_email\n"
. "From: $user_email\n";
if (!#mail($contact_email, $subj, $msg, $head)) {
$response['error'] = 'Error send message!';
}else{
$response['error'] = 'success!';
}
} else {
$response['error'] = 'Error send message!';
}
echo json_encode($response); die();
I know I'm being sent a status of '1' from this process file as my JavaScript resulting is functioning. Problem is that I'm not getting the email.
<?php
//Retrieve form data.
//GET - user submitted data using AJAX
//POST - in case user does not support javascript, we'll use POST instead
$name = ($_GET['name']) ? $_GET['name'] : $_POST['name'];
$email = ($_GET['email']) ?$_GET['email'] : $_POST['email'];
$comment = ($_GET['comment']) ?$_GET['comment'] : $_POST['comment'];
//flag to indicate which method it uses. If POST set it to 1
if ($_POST) $post=1;
//Simple server side validation for POST data, of course,
//you should validate the email
if (!$name) $errors[count($errors)] = 'Please enter your name.';
if (!$email) $errors[count($errors)] = 'Please enter your email.';
if (!$comment) $errors[count($errors)] = 'Please enter your comment.';
//if the errors array is empty, send the mail
if (!$errors) {
//recipient - change this to your name and email
$to = 'myemail#gmail.com';
//sender
$from = $name . ' <' . $email . '>';
//subject and the html message
$subject = 'Comment from ' . $name;
$message = '
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<table>
<tr><td>Name</td><td>' . $name . '</td></tr>
<tr><td>Email</td><td>' . $email . '</td></tr>
<tr><td>Comment</td><td>' . nl2br($comment) . '</td></tr>
</table>
</body>
</html>';
//send the mail
$result = sendmail($to, $subject, $message, $from);
//if POST was used, display the message straight away
if ($_POST) {
if ($result) echo 'Thank you! We have received your message.';
else echo 'Sorry, unexpected error. Please try again later';
//else if GET was used, return the boolean value so that
//ajax script can react accordingly
//1 means success, 0 means failed
} else {
echo $result;
}
//if the errors array has values
} else {
//display the errors message
for ($i=0; $i<count($errors); $i++) echo $errors[$i] . '<br/>';
echo 'Back';
exit;
}
//Simple mail function with HTML header
function sendmail($to, $subject, $message, $from) {
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
$headers .= 'From: ' . $from . "\r\n";
$result = mail($to,$subject,$message,$headers);
if ($result) return 1;
else return 0;
}
?>
You mentioned you are using GoDaddy. GoDaddy requires you set the sender address legitimately to match the domain of the site it is sending from or use SMTP with Authentication.
There is a huge gaping hole with this method of sending email. Spammers can easily override the From: header by inserting additional recipients.
I'm not sure how mail centric your application plans to be, but I would recommend using a package like PHPMailer or PEAR::Mail as it takes care of email handling for you at a much higher level. This let's you focus on more important parts of your application. The built-in PHP mail() feature is very limited in its abilities and as you try to extend your mail capabilities you'll run into many road blocks that the base mail() function just cannot handle without a lot of additional logic on your behalf (attachments, MIME-types, etc come to mind).
when testing mails you can test it directly to your server, php mail has a function that already runs on it. if you test it on xampp locally it will not send , unless you have set the php mailer in localhost. but for me its better to test it on server than in localhost.
I'm using a PHP contact form and it is sending mail to non gmail addresses, however when I set it to send to a gmail address, it doesn't get delivered (it doesn't even appear in junk mail).
I've heard of issues like this before - I'm not a web developer/expert so can anybody suggest code/configuration changes to my PHP contact form below which would essentially mean messages get delivered to gmail addresses?
I'm on a linux/WHM dedicated server.
<?php
error_reporting(E_NOTICE);
function valid_email($str)
{
return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*#([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
}
if(!empty($_POST['name']) && !empty($_POST['email']) && valid_email($_POST['email']) === true && !empty($_POST['comment']))
{
$to = "contactform#gmail.com";
$headers = 'From: '.$_POST['email'].''. "\r\n" .
'Reply-To: '.$_POST['email'].'' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
$subject = "Contact Form";
$message = htmlspecialchars($_POST['comment']);
if(mail($to, $subject, $message, $headers))
{
echo 1; //SUCCESS
}
else {
echo 2; //FAILURE - server failure
}
}
else {
echo 3; //FAILURE - not valid email
}
?>
Did you check to see if your PHP installation/server supports the Mail() function?
Also did you check to see if Gmail is treating your emails as spam? (they wont show up in the spam folder, they are just blocked)... Try sending it to a different address.
Set your script to send it from an email address that has an actual mailbox somewhere so you can check for bounces. If your script echoing 1, and can send to other addresses it suggests (to me at least), that it's gmail not liking you, rather than anything wrong with the script per se.
It also looks like you need to look into protecting this script from email injection. Just a suggestion though.