PHP: Send Mail with Attachment

By Xah Lee. Date: . Last updated: .

This page shows you how to send email with attached file, using PHP.

Sending email in php is extremely easy. All you have to do is call the “mail” function. But how do you send out email with attachment?

There are php packages that allows you to do that, however, they will often need installation of the package, and if you are using a web hosting service provider, sometimes that is not possible. Luckily, it is not difficult to write a simple code that does it. All you have to do is to encode your mail payload as multipart MIME .

Here's a simple working example of sending html mail with attached file:

<?php

$fromAddr = 'staff@example.com'; // the address to show in From field.
$recipientAddr = 'joe@example.org';
$subjectStr = 'Thank you';

$mailBodyText = <<<END89283
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Thank You</title>
</head>
<body>
<p>
<b>Login:</b> {$_POST['login']}<br>
<b>Password:</b> {$_POST['password']}<br>
</p>
</body>
</html>
END89283;

$filePath = 'uploaded_files/great_house.jpg';
$fileName = basename($filePath);
$fileType = 'image/jpeg';
/* to find out what string to use for type, see
 http://en.wikipedia.org/wiki/Internet_media_type
or $_FILES['attachment']['type'];
*/

/* encode the email content */

$mineBoundaryStr='otecuncocehccj8234acnoc231';

$headers= <<<EEEEEEEEEEEEEE
From: $fromAddr
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="$mineBoundaryStr"

EEEEEEEEEEEEEE;

// Add a multipart boundary above the plain message
$mailBodyEncodedText = <<<TTTTTTTTTTTTTTTTT
This is a multi-part message in MIME format.

--{$mineBoundaryStr}
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

$mailBodyText

TTTTTTTTTTTTTTTTT;

$file = fopen($filePath,'rb');
$data = fread($file,filesize($filePath));
fclose($file);
$data = chunk_split(base64_encode($data));

// file attachment part
$mailBodyEncodedText .= <<<FFFFFFFFFFFFFFFFFFFFF
--$mineBoundaryStr
Content-Type: $fileType;
 name=$fileName
Content-Disposition: attachment;
 filename="$fileName"
Content-Transfer-Encoding: base64

$data

--$mineBoundaryStr--

FFFFFFFFFFFFFFFFFFFFF;

if (
mail( $recipientAddr , $subjectStr , $mailBodyEncodedText, $headers )
) {
  echo '<p>Send successfully!</p>';
} else {
  echo '<p>Bah!</p>';
}

2009-09-07: Thanks to Andrew Szurley for correcting a formatting problems with the mine header, that causes this to not work in gmail or Windows Mail. (always worked in Apple Mail)