When I try to send a HTML encoded email from PHP, if the subject line contains special chars like "Here's the information you requested", PHP encodes it to read "Here's the information you requested."
How do I fix this?
Here's what the code looks like using PHP mail():
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'To: ' . $mod_params['name'] . '<' . $mod_params['email'] . '>' . "\r\n";
$headers .= 'From: <do_not_reply#a4isp.com>' . "\r\n";
$email_to = $mod_params['email'];
$email_sub = "Here's the Information You Requested";
$body = html_entity_decode("<html><body>" . $email_html_body . "</body></html>");
mail($email_to,$email_sub,$body,$headers);
It gives the same error as running it through the SugarPHPMailer class.
Try this:
$newsubject='=?UTF-8?B?'.base64_encode($subject).'?=';
This way you don't rely on PHP or the MTA's encoding, you do the job, and the mail client should understand it. No special characters will be present in your new subject, so no problems should arise while delivering the email.
I had a similar issue in a Wordpress plug-in I was working on and I racked my brain over and over trying different suggestions from here and in various other Google search results. I finally found a solution that worked in my situation so I'll share it. I will say it was Paul's solution which I tried at first and it didn't work, but the reason was me trying to "shorthand" the solution. In my case just calling html_entity_decode() didn't work. Why? If I had read the PHP doc more closely it would have been obvious. My issue was with encoding on a single quote and the default for html_entity_decode() is 'ENT_COMPAT' which leaves single quotes alone. The solution was to set all the parameters and that worked. In reality I probably could have left off the charset since I was encoding UTF-8, but figured I be thorough.
$decoded_str = html_entity_decode ( $value_to_decode, ENT_QUOTES, 'UTF-8' );
The lesson here is a good one, "Read the docs". I'm not saying that you didn't (you probably did), but lot's of us get in a hurry and gloss over the solution which is sitting there staring us in the face if we'd only look.
If the string really doesn't contain encoded values before you send, take a look at this:
$subject= mb_encode_mimeheader($subject,"UTF-8", "B", "\n");
// or
$subject= mb_encode_mimeheader($subject,"UTF-7", "Q", "\n");
Take a look at these posts related to SugarCRM:
http://www.sugarcrm.com/forums/showthread.php?t=11940
http://www.sugarcrm.com/forums/showthread.php?t=11106&highlight=iso-8859-1
You should use mb_encode_mimeheader, just remember to set before.
mb_internal_encoding("UTF-8"); //has to be set (of course your internal encoding may not be UTF-8).
$subject = mb_encode_mimeheader($subject,'UTF-8','Q');
It will take care of encoding to (the human readable) Quoted-printable when needed and automatically break the subject into the right amount of lines depending on lenght.
Try running the subject line through html_entity_decode(), looks like maybe you have some entities in the subject line.
Submitting the offending block of code often times will ensure you a better response faster. You are likely encoding the text somewhere before this action takes place. As previously suggested you can seek out that action, and correct it, or you can simply decode the subject line before sending the email.
Related
I have a simple web page where I get some data from $_POST that users input: comments, usernames, etc. And I send them to email and save them on database. My problem is what when I send to email, doesn't matter what client is, I only see gibberish. I tried declaring the meta tag in the emails with all iso 88xx, utf8, windows, etc., but with no success. Also tried a million examples of htmlentities(), all leading to the same thing... plain gibberish. (Althought the source code shows different things sometimes, the plain text never changes).
Example code:
if (isset($_POST['name'])) {
$name = htmlentities($_POST['name'], ENT_QUOTES);
}
A result of mail() of $name (Don Quijóte) would be something like this "Don Quijóte".
Sorry if this is a repost but I just can't get this working.
Have you tried setting the headers, something like...
// Always set content-type when sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:plain/text;charset=UTF-8" . "\r\n";
mail($to,$subject,$message,$headers);
This sets the encoding to UTF-8. More here:
http://www.w3schools.com/php/func_mail_mail.asp
It is surprisingly hard to send a mail in the right way. The error you get with Don Quijote is due to the fact that your string is in utf8 but it is showed with ISO8859 encoding. (That is why you get that weird A and a small 3.
I would recomend using php mailer You can get it here
It is way simpler to setup and it will be more efficient if you at some time in the future need to send out a lot of emails. (Because mail() opens and closes the connection on each call)
Also be aware that if you are using utf-8 everything should be with utf-8. Your database should be set to utf-8. You outputs to html and so on. Every step of the way you should be sure it is utf8.
I have a small issue with GMail. My company has a ".fr" part in its name, and when we send newletters, GMail shows it as an internet adress and autmatically adds a link to it.
That's not what I want.
I found a very good solution here, and it works like a charm when I manually edit the HTML file. The magic is to add a character GMail does not know, like , so that is does not transform the text into a link.
The problem is when I try to automate this replacement :
$body = str_replace('my company.fr', "my company.fr", $body);
PHP does not seem to see this character, and for the little story, neither does Google...
Do you know of a way to achieve my goal, that is not having a link on my company name ?
I could do the second option in the above mentioned article, but that, to my opinion, would be my last option.
Thanks for your replies !
You can need ' not " for this special char
$body = "my company.fr"
$body = str_replace('my company.fr', 'my company.fr', $body);
//result is my company.fr
And using html_entity_decode for back
$st = "my company.fr"
$st = html_entity_decode($st);
//result is my company.fr
Hope this help!
Hi this is my first time trying to use base64 encoding.
Everything seems to be fine with what I am trying to do, except when I send an email, it gives me all the tags (plain text) in the email and it doesn't display the HTML correctly.
Here is an example of how the email comes through:
html>body>center>table bgcolor="#012b2b" width="100%">tr>td align="center">img src="data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABGAAD...
I removed all the < firts brackets for this post.
What I have done so far is this:
$pathr = "http://www.aboutitgroup.com/dev/sbtours/files/6113/7059/1223/NewsLetter.jpg"
$sep = sha1(date('r', time()));
$attachment = file_get_contents($pathr);
$encoded = base64_encode($attachment);
$headers .= "MIME-Version: 1.0\r\n";
$headers .= " Content-Type: text/html;
boundary=\"PHP-mixed-{$sep}\"";
$headers .= "Content-Transfer-Encoding: base64";
$subject = 'Newsletter';
$messages ="... img src="data:image/jpg;base64,'.$encoded.'"/>...';
Could someone please explain why the message does not display in HTML but only plain text.
When I copy the email text that comes through, and save it as an HTML file it displays correctly.
Thank you.
This seems relevant: http://www.webdeveloper.com/forum/showthread.php?185299-Sending-a-HTML-email-in-base64-HELP
In particular:
To tell if the router is the problem try "quoted/printable" encoding type ...or maybe even 7bit ...it's not optimum but it should give you different results.
to test the server and client apps, make sure to specify the mime version and charset intended, its not always implied...also, since you are not doing the message in multipart and trying to display the message in line, I wouldn't even chunck-split it. Try:
$to = "kit#huntingsportsplus.net";
$subject = "$lastName, $firstName - $propertyCounties, $propertyStates - $totalAcreage Acres - $emailAddress";
mail ($to,$subject,$message,"From: info#hunt-private-land.com <info#hunt-private-land.com>\n"."MIME-Version: 1.0\n"."Content-type: text/html; charset=iso-8859-1");
Personally I'd use the Zend_Mail object - it saves you from having to do the hard work. Here's a good starting point: http://zend-framework-community.634137.n4.nabble.com/how-to-show-images-inside-a-html-Zend-Mail-td645323.html
Finally if you need to know how your message will render in different mail clients you can use Litmus to check this:
I'm looking for a way to download the whole raw email data (including attachment), similar to what you get by clicking "Show Original" in Gmail.
Currently, I can get the raw header and some parts of the mail body by this code:
$this->MailBox = imap_open($mailServer, $userName, $password, OP_SILENT);
...
$email->RawEmail = imap_fetchbody($this->MailBox, $msgNo, "0");
$email->RawEmail .= "\n".imap_fetchbody($this->MailBox, $msgNo, "1");
Also I know that changing the 3rd parameter of imap_fetchbody might return the encoded attachment. Guess I need a loop here to get the raw email part by part, but what's the condition to stop the loop?
Is there an easy way to get the whole email at once?
Any help would be appreciated.
I came across this question when I was searching for the same issue. I knew it had to be easier than the solution by hakre and I found the right answer on the page for imap_fetchbody on a post from 5 years ago.
To get the full raw message just use the following:
$imap_stream = imap_open($server, $username, $password);
$raw_full_email = imap_fetchbody($imap_stream, $msg_num, "");
Notice the empty string as third parameter of imap_fetchbody this signifies all parts and sub-parts of the email, including headers and all bodies.
The answer by hakre is overcomplete, if you don't really care about the structure then you won't need imap_fetchstructure.
For a simple 'Show Source' you should only need imap_fetchheader and imap_body.
Example:
$conn = imap_open('{'."$mailServer:$port/pop3}INBOX", $userName, $password, OP_SILENT && OP_READONLY);
$msgs = imap_fetch_overview($conn, '1:5'); /** first 5 messages */
foreach ($msgs as $msg) {
$source = imap_fetchheader($conn, $msg->msgno) . imap_body($conn, $msg->msgno);
print $source;
}
My answer is "overcomplete", see Boy Baukema's answer for a more straight forward "view source" way of doing if you don't need the whole structure of the email.
If you want to fetch all, you need to fetch
The headers imap_fetchheader.
Obtain the number of bodies the message has imap_fetchstructure.
Each mine-headers a body has imap_fetchmime.
Each body it has imap_fetchbody.
As mime-message can have multiple bodies, you need to process each part after the other. To reduce load to the server use the FT_PREFETCHTEXT option for imap_fetchheader. Some example code about imap_fetchstructure in another answer that shows handling the imap connection and iterating over parts of a message already through encapsulation.
A common mistake is to use "\n" or PHP_EOL.
According to RFC RFC821, RFC2060, RFC1939 "\r\n" should be used.
While some mailserver auto convert that mistakes, Cyrus does not and throw a nice error.
PHP_EOL is a system depending constant, it's "\n" on Linux, "\r" on Mac and "\r\n" on Windows, for example.
Furthermore imap_fetchheader() contains the trailing "\r\n" as expected. So the correct example would be:
$source = imap_fetchheader($conn, $msg->msgno) . imap_body($conn, $msg->msgno);
I've looked around here but could not find an answer regarding the problem that I am facing.
Most similar to my problems are in this: emails sent with php mail don't show up correctly in outlook , but I checked and the solution did not work for me.
I am basically writing a PHP script that sends out emails, with a table in it. The problem however, is that if I receive it in gmail, the email shows up fine, but it does not even come through to Outlook at all.
Examining the source code of emails that do make it through to Outlook, shows a line break for some reason (again not present in gmail)
Eg:
<td> xyz#aaa
tt.com </td>
When it should show up as:
<td> xyz#aaatt.com </td>
In my php code, I even try to remove the line returns and spaces (as there should be no spaces in emails)
$rmv = array("\n");
$lead_email = str_replace($rmv, "", $lead_email);
$rmv = array("\r");
$lead_email = str_replace($rmv, "", $lead_email);
$rmv = array(" ");
$lead_email = str_replace($rmv, "", $lead_email);
For reference, my mail header is as follows:
$headers = 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\n";
$headers .= 'From: helpdesk#viatechcrm.com' . "\n";
Btw should I use iso-8859-1 or utf-8? I occasionally encounter names with European characters.
Any help greatly appreciated!
EDIT: So I was examining the source code, and found something interesting. The message is really long, but it only shows 3-4 lines. I found that it gets cut off right about 991 characters, thus the email breaking up.. Is this something to do with the Mime-Version 1.0?
How can I increase the number of characters it can receive? I tried adding '\r\n' after every table row, but one of the 4 emails still does not show up for some reason
EDIT 2: Thanks everyone for the help! I finally figured it out, in a forum post dated back in 2009. For future reference, refer to the last posting:
http://forums.devarticles.com/php-development-48/formatting-a-newline-line-break-in-php-html-output-5274.html
You should use UTF-8 if you have non-alphanumeric characters. You should end each header line with a "\r\n", not just a plain "\n". Not sure if this will fix your problem as I can't test, but it is something that you should fix nontheless.
It sounds like you have only added "\r\n" to the HTML part of your message. All header lines must end in "\r\n", not just the lines in the body. Some clients and servers will cope with just "\n" but they really don't have to (see RFC 2822), hence the inconsistencies between Gmail and Outlook.