79

How can I send an HTML-formatted email with pictures using PHP?

I want to have a page with some settings and HTML output which is sent via email to an address. What should I do?

The main problem is to attach files. How can I do that?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Abadis
  • 2,671
  • 5
  • 28
  • 42

8 Answers8

175

It is pretty simple. Leave the images on the server and send the PHP + CSS to them...

$to = 'bob@example.com';

$subject = 'Website Change Request';

$headers  = "From: " . strip_tags($_POST['req-email']) . "\r\n";
$headers .= "Reply-To: " . strip_tags($_POST['req-email']) . "\r\n";
$headers .= "CC: susan@example.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";

$message = '<p><strong>This is strong text</strong> while this is not.</p>';


mail($to, $subject, $message, $headers);

It is this line that tells the mailer and the recipient that the email contains (hopefully) well-formed HTML that it will need to interpret:

$headers .= "Content-Type: text/html; charset=UTF-8\r\n";

Here is the link I got the information from... (link)

You will need security though...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris
  • 5,516
  • 1
  • 26
  • 30
  • what about css formating, pictures , and other files like js that a html file needs ? – Abadis Jun 28 '12 at 06:21
  • 4
    @UmerHayat agreed, but we all had to start somewhere, even if it is only learning how to Google stuff... – Chris Jun 28 '12 at 06:38
  • @Abadis - CSS can be done either way, embedded in the file or externally as per usual with a HTML file. Images can be packed with I think (i have never done it) or left on the server and linked to. Look up HTML images if you are unsure how they work :P – Chris Jun 28 '12 at 06:38
  • 8
    **NEVER** use `html`, `head` or `body` elements or you will cause absolute chaos on web-based email systems that actually follow (X)HTML standards. Also *if* sending HTML email *never* send a header level greater than `h2` as your email subject (on proper systems) will be in the single `h1` element on the page. If this does not make sense remember that Google attempts to interpret your page as a newspaper where there is only one main header (e.g. "We won the war!") and many smaller heads (e.g. "Kittens saved by disturbed moose"). – John Jun 26 '16 at 02:55
  • 5
    There is a typo in this section "$message .= ". This variable wasn't declared before. – madlopt Jul 14 '16 at 08:50
  • use "\n" not "\r\n" if you want make it working in gmail https://stackoverflow.com/a/10330378/4870273 – luky Feb 22 '18 at 19:38
  • Is it the same as setting `` ? – melvin Nov 03 '18 at 07:32
20

You need to code your HTML content using the absolute path for images. By absolute path, I mean you have to upload the images to a server and in the src attribute of images you have to give the direct path, like this <img src="http://yourdomain.com/images/example.jpg">.

Below is the PHP code for your reference: It’s taken from mail:

<?php
    // Multiple recipients
    $to  = 'aidan@example.com' . ', '; // Note the comma
    $to .= 'wez@example.com';

    // Subject
    $subject = 'Birthday Reminders for August';

    // Message
    $message = '
      <p>Here are the birthdays upcoming in August!</p>
    ';

    // To send HTML mail, the Content-type header must be set
    $headers  = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=UTF-8' . "\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";


    // Mail it
    mail($to, $subject, $message, $headers);
?>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Subhajit
  • 1,929
  • 3
  • 19
  • 21
12

I have this code and it will run perfectly for my site:

public function forgotpassword($pass, $name, $to)
{
    $body  = "<table width=100% border=0><tr><td>";
    $body .= "<img width=200 src='";
    $body .= $this->imageUrl();
    $body .= "'></img></td><td style=position:absolute;left:350;top:60;><h2><font color = #346699>PMS Pvt Ltd.</font><h2></td></tr>";
    $body .= '<tr><td colspan=2><br/><br/><br/><strong>Dear '.$name.',</strong></td></tr>';
    $body .= '<tr><td colspan=2><br/><font size=3>As per Your request we send Your Password.</font><br/><br/>Password is : <b>'.$pass.'</b></td></tr>';
    $body .= '<tr><td colspan=2><br/>If you have any questions, please feel free to contact us at:<br/><a href="mailto:support@pms.com" target="_blank">support@pms.com</a></td></tr>';
    $body .= '<tr><td colspan=2><br/><br/>Best regards,<br>The PMS Team.</td></tr></table>';
    $subject = "Forgot Password";
    $this->sendmail($body, $to, $subject);
}

Mail function

function sendmail($body, $to, $subject)
{
    //require_once 'init.php';

    $from = 'testing@gmail.com';
    $headersfrom = '';
    $headersfrom .= 'MIME-Version: 1.0' . "\r\n";
    $headersfrom .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $headersfrom .= 'From: ' . $from . ' ' . "\r\n";
    mail($to, $subject, $body, $headersfrom);
}

The image URL function is used for if you want to change the image. You have to it change in only one function. I have many mail functions, like for forgot password or create user. Therefore I am using the image URL function. You can directly set the path.

function imageUrl()
{
    return "http://" . $_SERVER['SERVER_NAME'] . substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], "/") + 1) . "images/capacity.jpg";
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jalpesh Patel
  • 3,150
  • 10
  • 44
  • 68
  • @Jalpesh So for a CSS file you would just do the same? Reference the absolute path and it should work, right? – Fernando Silva Apr 09 '14 at 23:24
  • 1
    @FernandoSilva you have to set absolute path and also set class or id to element so based on that you css will work – Jalpesh Patel Apr 10 '14 at 05:29
  • @Jalpesh Think I'll have to try something else, since Hotmail removes all floating css rules and Gmail simply clears out my classes. Not sure if I'm missing something, but I have my HTML prepared for data and css takes care of the layout. I'm using the PHPMailer class to send emails and I can't find any reference to this behaviour being caused by it, but I'm not sure tbh. Any ideas of what to look into? Images display correctly with inline styling on both btw. – Fernando Silva Apr 15 '14 at 23:11
10

Sending an HTML email is not much different from sending normal emails using PHP. What is necessary to add is the content type along the header parameter of the PHP mail() function. Here is an example.

<?php
    $to = "toEmail@domain.com";
    $subject = "HTML email";
    $message = "
    <html>
        <head>
            <title>HTML email</title>
        </head>

        <body>
            <p>A table as email</p>
            <table>
                <tr>
                    <th>Firstname</th>
                    <th>Lastname</th>
                </tr>
                <tr>
                    <td>Fname</td>
                    <td>Sname</td>
                </tr>
            </table>
        </body>
    </html>
    ";
    // Always set content-type when sending HTML email
    $headers = "MIME-Version: 1.0" . "\r\n";
    $headers .= "Content-type:text/html;charset=UTF-8" . "\r\b";
    $headers .= 'From: name' . "\r\n";
    mail($to, $subject, $message, $headers);
?>

You can also check here for more detailed explanations by W3Schools.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bonyem
  • 1,148
  • 11
  • 20
6

You can easily send the email with HTML content via PHP. Use the following script.

<?php
$to = 'user@example.com';
$subject = "Send HTML Email Using PHP";

$htmlContent = '
<html>
<body>
    <h1>Send HTML Email Using PHP</h1>
    <p>This is a HTMl email using PHP by CodexWorld</p>
</body>
</html>';

// Set content-type header for sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

// Additional headers
$headers .= 'From: CodexWorld<info@codexworld.com>' . "\r\n";
$headers .= 'Cc: welcome@example.com' . "\r\n";
$headers .= 'Bcc: welcome2@example.com' . "\r\n";

// Send email
if(mail($to,$subject,$htmlContent,$headers)):
    $successMsg = 'Email has sent successfully.';
else:
    $errorMsg = 'Email sending fail.';
endif;
?>

Source code and live demo can be found from here - Send Beautiful HTML Email using PHP

JoyGuru
  • 1,803
  • 20
  • 11
2

The simplest way is probably to just use Zend Framework or any of the other frameworks like CakePHP or Symfony.

You can do it with the standard mail function too, but you'll need a bit more knowledge on how to attach pictures.

Alternatively, just host the images on a server instead of attaching them. Sending HTML mail is documented in the mail() function documentation.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Martijn
  • 3,696
  • 2
  • 38
  • 64
  • @gonatee depends on what level of quality you want. The accepted answer is not going to work for all but the most basic cases. If basic cases is all you need, then using `mail()` will be just fine. If you need a more reliable solution or have complex situations or demands, it's probably best to rely on a a framework or library that has already been through the dozens of RFC documents and years of bug fixing. If you can find a dedicated library or a framework that let's you pick and choose the features you want, there is little reason to rely on figuring it all our yourself. – Martijn Mar 28 '17 at 10:22
2

Use PHPMailer.

To send HTML mail, you have to set $mail->isHTML() only, and you can set your body with HTML tags.

Here is a well written tutorial:

How to send mail using PHP

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rohitashv Singhal
  • 4,517
  • 13
  • 57
  • 105
1

The trick is to know the content id of the image MIME part when building the HTML body part.

It boils down to making the img tag—<img src="cid:entercontentidhere" />

Kronolith.php

Look at the function buildMimeMessage for a working example.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ralf Lang
  • 19
  • 1