Is there a way to attach an image to an html formatted email message created in PHP?
We need to ensure that a corporate logo is on emails sent to clients who may not have access to the internet whilst reading their email (They will obviously have it to download the files).
Try the PEAR Mail_Mime package, which can embed images for you.
You need to use the addHTMLImage() method and pass a content id (cid), which is a unique string of text you will also use in your img's src attribute as a cid: URL. For example:
include('Mail.php');
include "Mail/mime.php";
$crlf = "\r\n";
$hdrs = array(
'From' => 'foo#bar.org',
'Subject' => 'Mail_mime test message'
);
$mime = new Mail_mime($crlf);
//attach our image with a unique content id
$cid="mycidstring";
$mime->addHTMLImage("/path/to/myimage.gif", "image/gif", "", true, $cid);
//now we can use the content id in our message
$html = '<html><body><img src="cid:'.$cid.'"></body></html>';
$text = 'Plain text version of email';
$mime->setTXTBody($text);
$mime->setHTMLBody($html);
$body = $mime->get();
$hdrs = $mime->headers($hdrs);
$mail =& Mail::factory('mail');
$mail->send('person#somewhere.org', $hdrs, $body);
It's probably easiest to use some library that can deal with email attachments. For example, PEAR's Mail_Mime.
PEAR's Mail_Mime package is what you're after here.
Once you've set your message up, adding an attachment is as simple as:
$mime = new Mail_mime("\n");
$mime->setTXTBody($msg_text);
$mime->setHTMLbody($msg_html);
// Add gif as attachment to mail
$mime->addAttachment("/path/to/image/smile.gif", "image/gif");
$body = $mime->get();
$headers = $mime->headers($headers);
$mail->send("joe#bloggs.com", $headers, $body);
If you're looking for your logo to display in a particular place in the email - rather than solely as an attachment - you can do the following:
// In your message html:
<img src='logo.gif' alt='Our logo' />
// PHP:
$mime->addHTMLImage('/path/to/image/logo.gif');
This approach can have mixed results depending on your user's mail client, so before sending it out try testing your format on dummy gmail, yahoo and hotmail accounts.
Are you rolling your own, or using a
prefab class? I recommend PHP
Mailer[0] myself, and there's also
PEAR::Mail_Mime[1] among others that
Google would be happy to help you
find. I've been using PHP Mailer to
send messages with embedded images[2]
for years without a hitch, though bear
in mind that each image increases the
email's bandwidth weight hugely, so
generally it should not be used for
anything in bulk. And to echo Bill,
do make use of the text-only alternative too.
[0] http://phpmailer.sourceforge.net/
[1] http://pear.php.net/manual/en/package.mail.mail-mime.php
[2] http://phpmailer.sourceforge.net/docs/PHPMailer/PHPMailer.html#AddEmbeddedImage
taken from http://lists.evolt.org/archive/Week-of-Mon-20060612/183029.html
There are more than enough answers here that should help fix your specific problem, but I just thought it might be worth pointing out that you may well have a larger problem that you hadn't considered.
Specifically - writing emailers to be sent via PHP is filled with potential gotchas and should only be done if you have a really good idea of what can go wrong.
If you're planning on sending emails fairly intensively I would strongly suggest doing it through either a dedicated email marketing client or implementing one of the many email marketing API's out there that will send it for you. (mailchimp is apparently a decent one).
Try out swiftmailer here is a good example how to use embedded image http://swiftmailer.org/wikidocs/v3/embedding_images?s[]=embed
Related
All the information are from a form. when submit the form, I use php mail() to send all the information to my email box, but I don't know how to format all the informatioin which from the submitted form.
is there a way to format the email which displays as the following style.
if using mail() can get that,how do i do? or there is another way to get that, thank you.
Don't use mail().
Instead use the phpmailer class.
http://code.google.com/a/apache-extras.org/p/phpmailer/source/browse/trunk/class.phpmailer.php
http://phpmailer.worxware.com/
You call the class in your code.
require "includes/class.phpmailer.php";
Then you format your mail strings using HTML and a bit of common sense. To format the way you want you can use p and line breaks. Images, links, most of what you would think to use in html. It has worked well for me.
Tip: You don't want to include external css so your html might have to be a bit old school with text-align and setting width in using style.
edited.
call the include
require "includes/class.phpmailer.php";
then, set a few variables such as your message ... do your formatting.
$mail = new PHPMailer();
$mail->IsMail();
$mail->AddReplyTo($emailAddress, "Your Reply Name"); // could be $replayemail if set
$mail->AddAddress($mailto); // who you are emailing
$mail->SetFrom($emailAddress, "Your From Name"); // from email
$mail->Subject = $subject; // keep it simple, email header
$mail->MsgHTML($message); // format fun stuff in $message
$mail->Send();
You need to learn about PHP HTML mail.
IMO best school for PHP beginners: http://www.w3schools.com/php/func_mail_mail.asp
Set the headers like this
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
mail($to,$subject,$message,$headers);
This would allow you to send html in mail.You can apply styling too.
Could you advise me how do I go about preventing email injection in PHP mail() without losing original message data? E.g. if I need to allow user to use \r\n, To, CC etc, so I do not want to completely strip them away from the message - I still want them delivered, but without adding any additional headers or somehow allowing mail injection to happen.
Most of the advices on internet suggest stripping that data away completely - but I do not want to do that.
I am sending plain text (non HTML) messages through PHP mail() function.
What would you advise?
To filter valid emails for use in the recipient email field, take a look at filter_var():
$email = filter_var($_POST['recipient_email'], FILTER_VALIDATE_EMAIL);
if ($email === FALSE) {
echo 'Invalid email';
exit(1);
}
This will make sure your users only supply singular, valid emails, which you can then pass to the mail() function. As far as I know, there's no way to inject headers through the message body using the PHP mail() function, so that data shouldn't need any special processing.
Update:
According to the documentation for mail(), when it's talking directly to an SMTP server, you will need to prevent full stops in the message body:
$body = str_replace("\n.", "\n..", $body);
Update #2:
Apparently, it's also possible to inject via the subject, as well, but since there is no FILTER_VALIDATE_EMAIL_SUBJECT, you'll need to do the filtering yourself:
$subject = str_ireplace(array("\r", "\n", '%0A', '%0D'), '', $_POST['subject']);
Suppose you you want to put the email address of the visitor in the optional header field like so:
$headers = "From: $visitorEmailAddress";
However, if
$visitorEmailAddress
contains
"address#email.com\n\nBCC:spam#v1agra.com"
you've made yourself a spam host, opening the door for mail injection.
This is a very simple example, but creative spammers and malicious hackers can sneak potentially damaging scripts in your email, since email is sent as a plaintext file. Even attachments are converted plaintext, and they can easily send attachements by adding a mimetype content line.
If your form validation for the FROM and/or TO fields is OK, you have to look at the form validation for the body of the email. I'd strip out the '-=' and '=-' characters, and prevent users from typing plain HTML by using strip_tags().
Try this for a review of various options:
http://www.codeproject.com/Articles/428076/PHP-Mail-Injection-Protection-and-E-Mail-Validatio
It covers several options and tries to explain the benefits and risks of each.
Use a designated mime email library, like Mail_Mime:
<?php
include 'Mail.php';
include 'Mail/mime.php' ;
$mime = new Mail_mime();
$mime->setTXTBody("Message goes here");
$hdrs = $mime->headers(array(
'From' => 'you#yourdomain.com',
'Subject' => 'Test mime message'
));
$body = $mime->get();
$mail = &Mail::factory('mail');
$mail->send('postmaster#localhost', $hdrs, $body);
?>
I'm sending an email with some xheader.
When the recipient of the email replays to that email, i want to parse it, and get the content of that xheader from the mail i get by replay.
unfortunately, when i'm parsing the email i get back, i don't see my xheader.
(I printed the whole email, and the xheader is not there)
How can i do that in PHP with Zend Framework (i'm using Zend_Mail_Storage_Imap)?
Code:
$mail = new Zend_Mail_Storage_Imap(array(
'host' => 'pop.gmail.com',
'user' => 'a#gmail.com',
'password' => 'a',
'ssl' => 'SSL'
));
$count = $mail->countMessages();
$message = $mail->getMessage($count);
print_r($message);
//go through the message
foreach(new RecursiveIteratorIterator($message) as $part){
echo '*****************<br/>';
print_r($part);
echo '<br/>*****************<br/>';
//match parts content type to text/html - the one that maches is the message HTML body
if (preg_match('/.*text\/html.*/', $part->contentType)){
$body = $part->getContent();
}
$headers = $part->getHeaders();
if (isset($headers['X-aHeader'])){
echo $headers['X-aHeader'];
}
Thanks,
Boris.
Pekka gets points for the correct response here - X-headers in an original message will not necessarily be retained for any replies to that message. But, you're using Gmail, so you have another potential option.
Gmail allows plus addressing, so username#gmail.com will also receive mail for username+extra#gmail.com. If your X-aHeader content is alphanumeric, you can append it to your email address (e.g. a+headerdata#gmail.com). If your header content isn't alphanumeric, I'd recommend caching what you would put in the header locally on your system, and provide a uniqid as the email plus-address. When you receive a reply, you can use that uniqid to look up the data you cached locally.
This is a common technique for uniquely identifying recipients who reply to emails, or who perhaps bounce messages.
I don't completely understand and some documentation or help would be appreciated greatly :)
Using PHP I create a MIME by using ezcomponents Mail object. But what I do not understand is:
Do you create an S/MIME message from a original MIME by signing it with openssl_pkcs7_sign ? or do you create an S/MIME from scratch and sign it when its done?
Please bear with me as I try to understand the correct way of doing things.
EDIT: Found this piece of code to illustrate my question better
<?
// Setup mail headers.
$headers = array("To" => "someone#nowhere.net",
"From" => "noone#somewhere.net",
"Subject" => "A signed and encrypted message.");
// Sign the message first
openssl_pkcs7_sign("msg.txt","signed.txt",
"signing_cert.pem",array("private_key.pem",
"password"),array());
// Get the public key certificate.
$pubkey = file_get_contents("cert.pem");
//encrypt the message, now put in the headers.
openssl_pkcs7_encrypt("signed.txt", "enc.txt",
$pubkey,$headers,0,1);
$data = file_get_contents("enc.txt");
// separate header and body, to use with mail function
// unfortunate but required, else we have two sets of headers
// and the email client doesn't decode the attachment
$parts = explode("\n\n", $data, 2);
// send mail (headers in the Headers parameter will override those
// generated for the To & Subject parameters)
mail($mail, $subject, $parts[1], $parts[0]);
?>
Save yourself a lot of pain and route the messages you need signed through a MTA filter that is designed for the job, e.g. Gnu Anubis (SMTP proxy) or implement a milter
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
It looks like there are some great libraries out there to do DomainKeys signing of emails on C#/.NET, but I'm having a really hard time finding the same kind of support for PHP. Maybe I'm not looking in the right place?
The only one I found is http://php-dkim.sourceforge.net/; it looks incredibly hacky and supports PHP4 only. Considering how popular PHP is, and how critical DomainKeys are for email classification as non-spam, I'd expect better tools; do you know of any? Any other tricks you'd recommend?
Extra info: I'm using an external SMTP provider because I need to send out thousands of emails per day.
I'd recommend DKIM support at the MTA level so all your server generated email for a given domain is signed by default. (unless you have a really good reason to not sign all server generated email for a domain).
The best starting point in my googling to get DKIM setup on LAMP with dkim-milter and sendmail (on CentOS 5.2 in my case) was Jeff Atwood's post about sending emails through code.
I would agree with him that the first 2 things you should address are reverse PTR record and DKIM signing.
Also very important:
IP address of the box to send email not already being blacklisted.
make sure postmaster#emailsendingdomain.com is a valid email box
if your server generated email needs to appear to come from somewhere else (like a contact form needing to come from name/email provided in a form) follow these guidelines for email headers.
Here is the email ip address blacklist checker that I used.
Those 5 things will solve perhaps 95% of your email deliverability issues.
This Guide for Fedora/dkim-milter/postfix is also very good.
The PHP mail library I use for my app is PHPMailer 5.1 which has DKIM support (and is PHP 5 only), but after doing the research, I decided implementing at the sendmail level was a better solution. As you can see, even the author of PHPMailer 5.1 does not suggest DKIM at the PHP mail library level is the best solution http://dkim.worxware.com/.
Best of luck to you.
This is one that has been on my radar for a while and could not find a definitive answer to the original question in this thread anywhere on the web. I have now been able to implement sending DKIM signed SMTP email with PHP/Pear. Below are the steps required.
I found a modified version of the DKIM from http://www.ra726.net/blog/2010/07/20/sending-email-to-gmail-from-php-without-being-marked-as-spam/ (you can download it via http://www.ra726.net/php-dkim.zip). If you have already implemented DKIM and just need to make it work with SMP mail then all you need from this is the dkim.php file which, as the blog says, is slightly modified to handle headers passed as an array. In my code, I have named it dkimNEW.php.
Ensure you include most headers so that the MTA does not modify the message after you have signed it. In my limited research, the most added headers are the Date and Message-ID headers, thus my header array looks like this: Note: I used this for sending an html email, change to suit! Also, add your domain as the last part of the Message-ID
$headers = array(
'Subject' => $subject,
'From' => $from,
'To' => $to,
'MIME-Version' => '1.0',
'Date' => date('r'),
'Message-ID' => '<'.sha1(microtime(true)).'#yourdomain.com>',
'Content-Type' => 'text/html',
'Content-Transfer-Encoding' => 'quoted-printable',
); // end $headers
You will then get to utilize the modified dkim.php mentioned above to sign your email AND add the signature to the headers array, aka
require 'dkimNEW.php';
$dkim = AddDKIM($headers, $subject, $body);
$headers['DKIM-Signature'] = $dkim;
The rest of the code is the normal code to send email via SMTP with PHP/Pear. The full working code is:
<?php
require_once 'Mail.php';
require_once 'Mail/mime.php';
// set all of the parameters
$subject = 'Test of DKIM';
$from = 'My Name <myname#mydomain.com>';
$to = 'First Recipient <recipient1#domain.com>';
$pbody ='<html><head></head><body><h1>Done! DKIM test</h1>Result, next?</body></html>';
$text = strip_tags($pbody);
// create the headers
$headers = array(
'Subject' => $subject,
'From' => $from,
'To' => $to,
'MIME-Version' => '1.0',
'Date' => date('r'),
'Message-ID' => '<'.sha1(microtime(true)).'#mydomain.com>',
'Content-Type' => 'text/html',
'Content-Transfer-Encoding' => 'quoted-printable',
); // end $headers
// create the message
$mime = new Mail_mime("\n");
$mime->setTXTBody($text);
$mime->setHTMLBody($pbody);
// always call these methods in this order
$body = $mime->get();
$headers = $mime->headers($headers);
require 'dkimNEW.php' ;
$dkim = AddDKIM($headers, $subject, $body);
$headers['DKIM-Signature'] = $dkim;
// create the smtp mail object
$smtp_params = array(
'host' => 'mail.mydomain.com',
'auth' => true,
'username' => 'myUserName',
'password' => 'myPassWord',
); // end $smtp_params
$smtp = Mail::factory('smtp', $smtp_params);
// send the message
$recipients = array('recipient1#domain.com', 'recipient2#domain.com');
$mail = $smtp->send($recipients, $headers, $body);
?>
PS. Just in case you did not notice, replace values with your own!
Therefore, all that is essentially needed to make DKIM to work with SMTP email (or indeed the PHP mail) is to ensure that you specify all the headers that are added to your email by your MTA, then sign the headers, subject and body of the message, and finally include that signed portion with your header.
Have you try : phpMailDomainSigner It support DKIM-Signature and DomainKey-Signature in Object Oriented Style.
Here some example:
// Create mailDomainSigner Object
include_once './lib/class.mailDomainSigner.php';
$mds = &new mailDomainSigner($domain_priv,$domain_d,$domain_s);
$new_data = $mds->sign(
$mail_data,
"Message-ID:Subject:From:Content-Type:MIME-Version:Content-Transfer-Encoding:Received:To:Date",
true,true,false);
A class solely for DKIM which is a spin-off from PHPMailer, but with improvements regarding the respect of the RFC and nice-and-clean code :
https://sourceforge.net/projects/dkim-class-php/
Example :
include_once('dkim.class.php');
$dkim = new DKIM();
$dkim_header = $dkim -> get_DKIM_header($to, $subject, $message, $headers);
mail($to, $subject, $message, $dkim_header.$headers);