In a typical scenario when sending newsletters, you send to your userbase a nice HTML template with images that are loaded from the web, gaining the benefit of a small sized email message. But most email clients will not load remote images, passing the option to the user, thus making your email message look not so awesome as it should.
To overcome this problem, we can embed the images in the email. This will increase the size of your email but it will definitely look the way you intented to. With PHPMailer, you use the AddEmbeddedImage() function which simply adds the image to the class's attachments array to be written later in the e-mail's body. Then you replace the src attribute of the image tag with the id of the attached object.
$this->AddEmbeddedImage('/path/to/image.jpg', 'my-image', 'attachment', 'base64', 'image/jpeg');
// replace source with id
<img src="cid:my-image" alt="" />
This is OK if you are sending one single image, but for more images that are contained in your HTML template, you need an automatic way to do this. Here is the custom function I have written for this.
// get all img tags
preg_match_all('/<img.*?>/', $body, $matches);
if (!isset($matches)) return;
// foreach tag, create the cid and embed image
$i = 1;
foreach ($matches as $img)
// make cid
$id = 'img'.($i++);
// replace image web path with local path
preg_match('/src="(.*?)"/', $body, $m);
if (!isset($m)) continue;
$arr = parse_url($m);
if (!isset($arr['host']) || !isset($arr['path']))continue;
$this->AddEmbeddedImage('/home/username/'.$arr['host'].'/public'.$arr['path'], $id, 'attachment', 'base64', 'image/jpeg');
$body = str_replace($img, '<img alt="" src="cid:'.$id.'" style="border: none;" />', $body);
Possibly you will have to adjust the code to work for your project. The key point is to convert the images' web path to the local one in the filesystem. I use the domain name as the project's folder, so to convert the web path to local I use PHP's parse_url() function to grab the host name and the rest of the path to the image file. For this to work it is assumed that the web path is also absolute in the HTML template... otherwise they images would never show to the user upon reading your email message.
Code with Love.