How to Send mail with an attachment in PHP

i would like to send a mail with an attachment with the php mail function. I can receive a mail. Unfortunately the image is broken. The image is in the same directory as the php script.

My source code for the script:

$name = "Name goes here";
$email = "recipient@gmail.com";
$to = "$name <$email>";
$from = "Sender";
$subject = "Here is your attachment";
$fileatt = "test.jpg";
$fileatttype = "image/jpeg";
$fileattname = "test.jpg";
$headers = "From: $from";

// File
$file = fopen($fileatt, 'rb');
$data = fread($file, filesize($fileatt));
fclose($file);

// This attaches the file
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$headers .= "\
MIME-Version: 1.0\
" .
"Content-Type: multipart/mixed;\
" .
" boundary=\\"{$mime_boundary}\\"";
$message = "This is a multi-part message in MIME format.\
\
" .
"-{$mime_boundary}\
" .
"Content-Type: text/plain; charset=\\"iso-8859-1\
" .
"Content-Transfer-Encoding: 7bit\
\
" .
$message .= "\
\
";

$data = chunk_split(base64_encode($data));
$message .= "--{$mime_boundary}\
" .
"Content-Type: {$fileatttype};\
" .
" name=\\"{$fileattname}\\"\
" .
"Content-Disposition: attachment;\
" .
" filename=\\"{$fileattname}\\"\
" .
"Content-Transfer-Encoding: base64\
\
" .
$data . "\
\
" .
"-{$mime_boundary}-\
";

// Send the email
if(mail($to, $subject, $message, $headers)) {

    echo "The email was sent.";

}
else {

    echo "There was an error sending the mail.";

}

I know this doesn’t answer your question directly but this is very easy to do using a library like SwiftMailer. I highly recommend taking full advantage of that library to handle emails. Especially, when it comes to embedding media since the library makes it super simple to do.

Or PHPMailer. Just from a quick glimpse, I don’t see any obvious issues, but I’d have to compare it to what PHPMailer does for attachments to be sure.

The image data ($data) is never sent

$data = chunk_split(base64_encode($data));
$message .= "--{$mime_boundary}\
" .
"Content-Type: {$fileatttype};\
" .
" name=\\"{$fileattname}\\"\
" .
"Content-Disposition: attachment;\
" .
" filename=\\"{$fileattname}\\"\
" .
"Content-Transfer-Encoding: base64\
\
" .
$data . "\
\
" .
"-{$mime_boundary}-\
";

// Send the email
if(mail($to, $subject, $message, $headers)) {

BTW, your boundaries are not quite right

This is a multi-part message in MIME format.

-==Multipart_Boundary_x2e1c894159a40c2de5b2da24f38514d6x
Content-Type: text/plain; charset="iso-8859-1
Content-Transfer-Encoding: 7bit



--==Multipart_Boundary_x2e1c894159a40c2de5b2da24f38514d6x
Content-Type: image/jpeg;
 name="Parrots-t.jpg"
Content-Disposition: attachment;
 filename="Parrots-t.jpg"
Content-Transfer-Encoding: base64




-==Multipart_Boundary_x2e1c894159a40c2de5b2da24f38514d6x-

Fabien Protencier

Not sure what you want me to gleam from that, both projects work, they get the job done and hide it behind an easy to use API. What I initially meant was that I’d have to compare the OP’s code to what PHPMailer does with attachments to see where they differ and if that was the reason he wasn’t getting the expected results.

Well one is managed by one of the leaders within the PHP community the other is well…

I’m sure there are some differences but I’ve never used PHPMailer myself. I would find it hard to believe that PHPMailer is *better than Swift Mailer considering the quality SensioLabs products.

None the less, to each their own.

Ah, I’ve only used it once, and it did exactly what I needed with very little configuring/code needing to be implemented. Good to know. Next time I need something I’ll have to check out SwiftMailer too.

@captainccs;

Forgive my ignorance. I’m a php novice. But I have a similar issue as the OP – in fact, it looks like we mayhave grabbed the original source code from the same place. It looks like from your response above that you pointed out two areas that prevent the image from sending: the $data variable and the boundary markers aren’t quite right. Could you offer a possible solution for both of these – I would like to amend my code as well. I’m trying to attach a PDF file as opposed to a JPG image. The strange thing about my situation is that my script sends a zip file attachment properly to the email with no issue-- however, when I amend the script it successfully sends a PDF attachment – except when I try to open the PDF --then Adobe Acrobat reader claims the file attachment was damaged and was not encoded properly. Do you mind taking a look at my code and explaining how I might go about fixing it? You are the first person I’ve found that could actually troubleshoot and diagnose the issue. I would really appreciate some guidance. Thanks so much!

<?php
$file_path = "http://www.mitchellmetals.net/images/drawings_walkway/w1.pdf"; // server path where file is placed
$file_path_type = "application/pdf"; // File Type
$file_path_name = "w1.pdf"; // this file name will be used at reciever end
$headers .= 'Content-type: text/html; charset=utf-8' . "\\r\
";
$from = "noreply@mitchellmetals.net"; // E-mail address of sender
$to = $_POST['email']; // E-mail address of reciever
$subject = "Drawing from Mitchell Metals"; // Subject of email
$message = "Thank you for downloading the <b>Walkway Canopy with Beams PDF file</b> from mitchellmetals.net. For a free estimate or budget number on a canopy, please email us at <a href='mailto:sales@mitchellmetals.net'>sales@mitchellmetals.net</a>. Please call 770-431-7300 if Mitchell Metals can assist you with your next project.";

$headers = "From: ".$from;

$file = fopen($file_path,'rb');
$data = fread($file,filesize($file_path));
fclose($file);

$rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$rand}x";

$headers .= "\
MIME-Version: 1.0\
" .
"Content-Type: multipart/mixed;\
" .
" boundary=\\"{$mime_boundary}\\"";

$message .= "This is a multi-part message in MIME format.\
\
" .
"--{$mime_boundary}\
" .
"Content-Type:text/html; charset=\\"iso-8859-1\\"\
" .
"Content-Transfer-Encoding: 7bit\
\
" .
$message .= "\
\
";


$data = chunk_split(base64_encode($data));

$message .= "--{$mime_boundary}\
" .
"Content-Type: {$file_path_type};\
" .
" name=\\"{$file_path_name}\\"\
" .
"Content-Disposition: attachment;\
" .
" filename=\\"{$file_path_name}\\"\
" .
"Content-Transfer-Encoding: base64\
" .
$data .= "\
\
" .
"--{$mime_boundary}--\
";

if(@mail($to, $subject, $message, $headers)) {
echo "File sent!";

} else {
echo 'Failed';
}
?>