I need a set of mail headers to attach to my mail() function in PHP. I send emails with HTML in them, and sometimes services like Yahoo Mail block them. Therefore I need to make sure that I am at least providing the right headers.
My code:
// To send HTML mail, the 'Content-type' header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
// Additional headers
$headers .= 'From: MyCompany <welcome#mycompany.com>' . "\r\n";
Is there anything else I should add?
$headers = "From: testsite <mail#testsite.com>\n";
$headers .= "Cc: testsite <mail#testsite.com>\n";
$headers .= "X-Sender: testsite <mail#testsite.com>\n";
$headers .= 'X-Mailer: PHP/' . phpversion();
$headers .= "X-Priority: 1\n"; // Urgent message!
$headers .= "Return-Path: mail#testsite.com\n"; // Return path for errors
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=iso-8859-1\n";
Most MUA's insert a lot of extra headers; however, here is sort of the bare minimum you can expect.
To:
Subject:
Date:
MIME-Version:
Content-type:
If you using HTML, then you should probably be using multipart messages--but it's not strictly necessary.
When defining if a sender is a possible spammer, many services check if the domain of the sender looks like a dialup user.
Quote from Wikipedia:
One e-mail anti-spam technique:
checking the domain names in the rDNS
to see if they are likely from dialup
users, dynamically assigned addresses,
or other inexpensive internet
services. Owners of such IP addresses
typically assign them generic rDNS
names such as
"1-2-3-4-dynamic-ip.example.com."
Since the vast majority, but by no
means all, of e-mail that originates
from these computers is spam, many
spam filters refuse e-mail with such
rDNS names.
Did the mail really come from 'mycompany.com'? I've had problems with some mail services blocking if it didn't really come from the SMTP server that the mail says it does.
A way around this, for me, was making the from to be automail#mydomainnaim.com and adding a reply-to, being the person who sent the mail using my system.
PHP 7.2+ solution
In current versions of PHP it is possible to pass an array of headers to mail() (as mentioned in the PHP docs), so the code could look a little cleaner. (Sablefoste mentioned this in their comment on the current top answer.)
In case anybody is interested, it could look like this:
$headers = [
'From' => 'testsite <mail#testsite.com>',
'Cc' => 'testsite <mail#testsite.com>',
'X-Sender' => 'testsite <mail#testsite.com>',
'X-Mailer' => 'PHP/' . phpversion(),
'X-Priority' => '1',
'Return-Path' => 'mail#testsite.com',
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=iso-8859-1'
];
mail('recipient#host.com', 'My subject', 'My message', $headers);
The RFCs for both IMF and MIME define the minimal set of headers, so this would be a good place to start.
For IMF, look here: https://www.rfc-editor.org/rfc/rfc5322#section-3.6
For MIME, look here: https://www.rfc-editor.org/rfc/rfc2045#section-3
The link below could be of some use defining the mandatory headers as:
Date:
The date the message was originated/written.
From:
The person "responsible" for the message.
Related
Is it possible to manipulate the date header using PHP's mail function/sendmail (website server is linux so I believe it's using sendmail underneath)?
I'm trying to test error handling of a (windows based) email checker, and need to generate an invalid date header in a message, but when I send my message using php mail, even though I am including a custom Date header, it seems to get overridden by the mail server and my custom header ignored. I'm guessing I might need an additional parameter for sendmail to tamper with that header, but I can't seem to find what that parameter would be, or whether this is even possible.
Here is what I am sending (with the personal domain info removed)
$headers = "From: ..................\r\n";
$headers .= "Message-ID: <" . md5(uniqid(time())) . "#..................>\n";
$headers .= "MIME-Version: 1.0\n";
//$headers .= "Date: ".date("D, d M Y H:i:s") . " UT\n"; //a valid header for comparison
$headers .= "Date: Tuesday\n"; // intentionally bogus email header
$headers .= "Reply-To: ..................\n";
$headers .= "Return-Path: ..................\r\n";
$headers .= "X-Priority: 3\r\nX-MSMail-Priority: Normal\n";
$headers .= "X-Mailer: PHP/".phpversion()."\n";
$headers .= "Content-type: text/plain; charset=iso-8859-1\n";
$headers .= "\n";
$success=mail($to, $s_subject, $s_emailmsg, $headers);
Assuming you wrote an email checker that runs via procmail, an easier way might be to construct an email message yourself and send that directly to the test script via standard input.
It's easier to write unit tests that way as it bypasses any interference by other mail servers. When you do follow this, make sure that the first line starts with MAIL FROM xx#yy.com.
I'm trying to send email from PHP, and although it's working, I'm noticing that I'm getting a lot of extra stuff in the "from" part of the email. The extra stuff, I'm assuming, is
information from my server?
For example, if $from = "myname", instead of "myname" only coming through in the email from field as is, I get something like:
myname#p3nlhg.phx3.secureserver.net
Here is my PHP I'm playing with, the important part being my $from var:
$from = "myname";
mail($to,$formSubj,$formMssg,$from);
Honestly that's all I have, nothing more or less (as far as the $from is concerned). How can I clean this up or make it so that only the plain value of $from, which is in this case "myname", comes out?
The 4th parameter of the mail function doesn't work this way. It expect header information. To achieve what you want to do use:
$header = "From: myname <no-reply#test.com> \r\n";
mail($to,$formSubj,$formMssg,$header);
You shouldn't use a lonely myname either. You need a valid email addess string: myname <no-reply#test.com> or no-reply#test.com. If you just put myname, PHP will try to interpret it as an email address. That's why you're getting myname#p3nlhg.phx3.secureserver.net. p3nlhg.phx3.secureserver.net must be the hostname of your server.
A nice thing about the header parameter is that you can use it to specify other less common fields. e.g.:
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From: Birthday Reminder <birthday#example.com>' . "\r\n";
$headers .= 'Cc: birthdayarchive#example.com' . "\r\n";
$headers .= 'Bcc: birthdaycheck#example.com' . "\r\n";
Notice that you need to place a carriage-return/line-feed (\r\n) at the end of each header attribute. A simple line feed will not work.
According to the mail documentation, you're using $from as the $additional_headers argument.
Instead, change $from to an appropriate header. For example,
$from = "myname";
$headers = "From: $from <user#example.com>";
mail($to, $formSubj, $formMssg, $headers);
According to the documentation for additional_headers,
When sending mail, the mail must contain a From header. This can be set with the additional_headers parameter, or a default can be set in php.ini.
Failing to do this will result in an error message similar to Warning: mail(): "sendmail_from" not set in php.ini or custom "From:" header missing. The From header sets also Return-Path under Windows.
It's coming from the mail server that you have installed in your server, try to switch to another one, like postfix, courier or someting else.
I have a problem with a mailing application I'm currently developing with php on a linux server. After sending an email to a bunch of different addresses with different clients on it, sometimes these mails can't be read by the receivers.
For example the body appears to start with this:
boundary="=_2cac04098ebf51c342bd57eab2200e38"
Message-ID: <lo5huc.id4ip6qutsch.lforce.de>
Date: Mon, 11 Jul 2011 06:01:24 +0200 (CEST)
--=_2cac04098ebf51c342bd57eab2200e38
I really have no clue what's happening to my mails. Each line in the header is separated by \n, the boundary entry has a leading \t. Though the client seems to read a line break which is not there while parsing my header. It also happens in other parts of the header.
Has anyone ever had a similar problem? Please help me!
Andy
UPDATE: I'm pretty sure it's no coding error. I've been coding this mail stuff for years (even wrote my own mail client) and it worked perfectly. Right now we use the RMAIL class which is also from a bigger open source project. I think it's more like a problem with my system configuration... but that's just a guess.
Make sure you seperate every header line correctly, for instance:
<?php
//To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
// Additional headers
$headers .= 'To: Mary <mary#example.com>, Kelly <kelly#example.com>' . "\r\n";
$headers .= 'From: Birthday Reminder <birthday#example.com>' . "\r\n";
$headers .= 'Cc: birthdayarchive#example.com' . "\r\n";
$headers .= 'Bcc: birthdaycheck#example.com' . "\r\n";
// Mail it
mail($to, $subject, $message, $headers);
?>
I suggest using PHPMailer, easy to use, takes care of all nesseccery headers, easy attachment sending, multiple recipients etc.
http://phpmailer.worxware.com/index.php?pg=phpmailer
I have a website in which I send a confirmation mail as part of the registration process.
Some time ago, I had some troubles with the mails I sent since I used no headers (PHP mail function).
Once I put some headers, I've gotten more responses from users, but I suspect that not every message reaches its destination.
How can I be sure that the messages reach their destination?
Which are the headers that can be considered a 'must'?
This is the code of my SendMail function
mail($to,
$subject,
$message,
"MIME-Version: 1.0\n".
"Content-type: text/plain; charset=ISO-8859-1; format=flowder\n".
"Content-Transfer-Encoding: 8bit\n".
"Message-Id: <" . md5(uniqid(microtime())) . "#mysite.com>\n".
"Return-Path: <admin#mysite.com>\n".
"X-Mailer: PHP v".phpversion()."\n".
"From: admin# mysite.com");
You should use external library for working with e-mails in php like PhpMailer , SwiftMailer or Zend_Mail. All your problems will go away.
The headers need a white space at the bottom to separate the header from main body.
Tools like Spam Assassin will give you a big mark down for that.
Also you should use \r\n as a line terminator instead of just \n
From PHP.net
Multiple extra headers should be separated with a CRLF (\r\n).
The headers seems quite good to me. The only glitch I see is an extra whitespace in the From header.
I'm sure you already checked it, but just in case ...
"From: admin# mysite.com");
should be (?)
"From: admin#mysite.com");
This is a working mail function I'm using for html mail and variable $return is defined to get error report from mail server in case of fail delivery.
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
$headers .= 'From: <'.$from.'>' . "\r\n";
$return = '-f'.$from;
#mail($to, $subject, $msg, $headers, $return);
you can see more detail at here sugunan.com
The headers look ok, except for the details pointed by #Eineki. Also if you are using Windows you need to send the $to param in the form "user#mail.com" and not "Username ", because it may cause trouble, due to the way the mail() function is implemented on windows platform, the "to" address may be parsed incorrectly.
You should add a Date: header (its mandatory by RFC5322) and some mail-clients may assume January 1 1970 as an e-mail date if none is given (and it gets lost between all the other old messages).
I am trying to send an email from a site I am building, but it ends up in the yahoo spam folder. It is the email that sends credentials. What can I do to legitimize it?
$header = "From: site <sales#site.com>\r\n";
$header .= "To: $name <$email>\r\n";
$header .= "Subject: $subject\r\n";
$header .= "Reply-To: site <sales#site.com>" . "\r\n";
$header .= "MIME-VERSION: 1.0\r\n";
$header .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$phpversion = phpversion();
$header .= "X-Mailer: PHP v$phpversion\r\n";
mail($email,$subject,$body,$header);
Don't use HTML in your email.
Send it via a legitimate mail server with a static IP and reverse-DNS (PTR) that points to the machine's real host name (and matches a forward lookup).
Include a Message-ID (or ensure that the local mailer adds one for you).
Run your email through SpamAssassin and see which bad-scoring rules it matches. Avoid matching them.
Use DomainKeys Identified Mail to digitally sign your messages.
I just successfully tried the following from my Yahoo! Web Hosting account:
$email = "me#site.com";
$subject = "Simple test";
$body = "Simple test";
$header = "From: site \r\n";
$header .= "To: $name \r\n";
$header .= "Subject: $subject\r\n";
$header .= "Reply-To: site " . "\r\n";
$header .= "MIME-VERSION: 1.0\r\n";
$header .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$phpversion = phpversion();
$header .= "X-Mailer: PHP v$phpversion\r\n";
mail($email,$subject,$body,$header);
However, you have some duplication in your header you should only need to do the following:
$email = "me#site.com";
$subject = "Simple test";
$body = "Simple test";
$header = "From: site \r\n";
$header .= "MIME-VERSION: 1.0\r\n";
$header .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$phpversion = phpversion();
$header .= "X-Mailer: PHP v$phpversion\r\n";
mail($email,$subject,$body,$header);
In addition to Ted Percival's suggestions, you could try using PHPMailer to create the emails for you rather than manually building the headers. I've used this class extensively and not had any trouble with email being rejected as spam by Yahoo, or anyone else.
There is also the possibility that 'sendmail' (which is underneath the PHP mail() function) needs extra parameters. If you have a problem with return headers (such as Return-Path) not being set with what you set them to be, you may need to use the fifth mail() parameter. Example:
mail('recipient#domain.com', 'Subject', $mail_body, $headers, " -f sender#domain.com");
There is some further evidence that true vanilla sendmail may have problem with this! Hopefully you have 'postfix' as PHP's underlying mail() support on your target server.
In addition to Ted Percival's suggestions, make sure that the IP address the email is coming from is a legitimate source for email according to the SPF record of site.com. If site.com doesn't have an SPF record, adding one (which allows the IP address in question, of course) may help get the emails past spam filters.
And if absolutely do need to use HTML in your email, make sure that you also include a plain text version as well; you'd use the content type of "multipart/alternative" instead of "text/html".
Ted's suggestions are good, as are Tim's, but the only way I've ever been able to reliably get email through to Yahoo/Hotmail/etc is to use the PEAR email classes. Try those & (assuming your server is OK) I can pretty much guarantee it'll work.
Ted and Tim have excellent suggestions. As does Shabbyrobe. We use PHPMailer and don't have any problems with spam filters.
One thing to note is that many spam filters will count NOT having a text version against you if you are using a MIME format. You could add all of the headers and the text version yourself, or just let PHPMailer or the PEAR mail library take care of that for you. Having a text version may or may not help, but it is good practice and user friendly.
I realize that your code sample is just that - a sample, but it is worth saying: Do not ever just drop user provided data into your mail headers. Make sure you validate that it is data you expect. It is trivial to turn a php mail script into an open relay, and nobody wants that.
Check rfc 822 and rfc 2045 for email format. I find python's Email class really easy to work with. I assume php's PEAR does the same (according to earlier mails). Also the header and the body are separated by a "\r\n\r\n", not sure if your code automatically inserts that, but you can try appending that to the header.
I dont think that DK/SPF might be necessary (since there are lots of webservers out there without DK/SPF support). There can be alot of factors that might be causing it to get blocked(atleast 10K different criterions and methods.. p0f,greylisting,greylisting, blacklisting etc etc). Make sure that your email is properly formatted(this makes a BIG difference). Look into libraries that generate the complete header for you.. that way you have least chances of making any mistake.
Adding a SPF record is very easy. You should try.
This one is for dreamhost plus googlemail
You should also ad you webserver ip address (in my case, the line before googlemail)
The last line tells the server to do a soft reject (mark as spam but don't delete) I'm using it instead of "-" (delete) because google documentation says so :-)
It's a TXT record
v=spf1
ip4:64.111.100.0/24 ip4:66.33.201.0/24 ip4:66.33.216.0/24
ip4:208.97.132.0/24 ip4:208.97.187.0/24 ip4:208.113.200.0/24 ip4:208.113.244.0/24
ip4:208.97.132.74 ip4:67.205.36.71
include:aspmx.googlemail.com
mx ~all
Hope it helps