PHP mail() attachment problems
$to = "myemail@mydomain.com";
$from = "Website <website@mydomain.com>";
$subject = "Test Attachment Email";
$separator = md5(time());
// carriage return type (we use a PHP end of line constant)
$eol = PHP_EOL;
// attachment name
$filename = "document.pdf";
//$pdfdoc is PDF generated by FPDF
$attachment = chunk_split(base64_encode($pdfdoc));
// main header
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"";
// no more headers after this, we start the body! //
$body = "--".$separator.$eol;
$body .= "Content-Transfer-Encoding: 7bit".$eol.$eol;
$body .= "This is a MIME encoded message.".$eol;
// message
$body .= "--".$separator.$eol;
$body .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$body .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$body .= $message.$eol;
// attachment
$body .= "--".$separator.$eol;
$body .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$body .= "Content-Transfer-Encoding: base64".$eol;
$body .= "Content-Disposition: attachment".$eol.$eol;
$body .= $attachment.$eol;
$body .= "--".$separator."--";
// send message
if (mail($to, $subject, $body, $headers)) {
echo "mail send ... OK";
} else {
echo "mail send ... ERROR";
}
What I've done:
- Separated the body from the headers
- removed extra EOLs put before separators
PHP Mail attachment not opening or error file
You are missing the attachment part in the email body.
Try this:
if (isset($_POST["send"])) {
$subject = "Applicant";
$name = $_POST['contact_name'];
$position = $_POST['position'];
$tmpName = $_FILES['attachment']['tmp_name'];
$fileType = $_FILES['attachment']['type'];
$fileName = $_FILES['attachment']['name'];
$message = "Name: ".$name."\r\n"."Position: ".$position;
# Open a file
# encode the data for safe transit
# and insert \r\n after every 76 chars.
$encoded_content = chunk_split(base64_encode(file_get_contents($tmpName)));
# Get a random 32 bit number using time() as seed.
$random_hash = md5(date('r', time()));
# Define the main headers.
$headers = "From: no-reply@example.com\r\n";
$headers .= "Reply-To: no-reply@example.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"\r\n";
$headers .= "X-Priority: 3\r\n";
$headers .= "X-MSMail-Priority: Normal\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
# Plain text section
$body = "--PHP-mixed-" . $random_hash . "\r\n";
$body .= "Content-Type: text/plain; charset=\"UTF-8\"\r\n";
$body .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$body .= $message;
$body .= "\r\n\r\n";
$body .= "\r\n--PHP-mixed-" . $random_hash . "\r\n\r\n";
# Define the attachment section
$body .= "--PHP-mixed-" . $random_hash . "\r\n";
$body .= "Content-Type: " . $fileType . "; name=\"" . $fileName . "\"\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
$body .= "Content-Disposition: attachment; filename=\"" . $fileName . "\"\r\n\r\n";
$body .= $encoded_content;
$body .= "\r\n--PHP-mixed-" . $random_hash . "\r\n\r\n";
# Send email now
$retval = mail('sample@gmail.com', $subject, $body, $headers);
if( $retval == true ) {
echo "<div style='border-style: solid; border: thick double #00386c; margin-bottom: 10px;'><h1 style='text-align: center; color: #00386c; padding: 10px;'>Your resume was sent! Thank you.</h1></div>";
} else{
echo "error";exit;
}
}
PHP mail sends attachments successfully, but the message is empty
Resolved by adding $body .= $message.$eol;
before the PDF-attachment.
PHP mail PDF attachment gets file corrupted
It's been a while, but finally got this problem solved. The issue is on PHP_EOL which in my case is returning \n, while some systems the email should have \r\n as line break.
To fix this issue just place the new $eol:
$eol = "\r\n";
php mail attachment - error - how to debug
This one works....
$text = "Hello Mr. Xyz," . $crnl . "Some stupid text as an example." . $crnl;
$content = chunk_split(base64_encode($file));
$headers = "MIME-Version: 1.0" . $crnl;
$headers .= "From: " . $mail_from . $crnl;
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $boundary1 . "\"" . $nl . $crnl;
$headers .= "Content-Type: text/plain" . $nl;
$headers .= "--" . $boundary1 . $crnl;
$headers .= 'Content-Length: '.strlen($text) . $crnl;
$headers .= "Content-Transfer-Encoding: 8-bit" . $nl . $crnl;
$headers .= $text;
$headers .= "--" . $boundary1 . $crnl;
$headers .= "Content-Type: application/excel; charset=\"ISO8859-1\"; name=\"xyz.csv\"" . $nl . $crnl;
$headers .= "--" . $boundary1 . $crnl;
$headers .= "Content-Disposition: attachment; filename=\"xyz.csv\"" . $crnl;
$headers .= 'Content-Length: ' . strlen($content) . $crnl;
$headers .= "Content-Transfer-Encoding: base64" . $nl . $crnl;
$headers .= $content;
$headers .= "--" . $boundary1 . "--"
...with a small bug. I have an extra attment, but that's for now ok. We other thing is a longer play with "\n", "\r\n" and a mixture of both on the right places (lines).
Issues with PHP email attachment
Answer
You propably should use an email library as was mentioned in one of the comments, but if you must use mail()
, your code should look something like this:
//standard mail headers
$header = "From: $from\r\n";
$header .= "Reply-To: $replyto\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"$uid\"\r\n\r\n";
Stop right there! The double line-break (\r\n\r\n
) marks the end of the headers. I don't know if mail()
allows you to send the body like this. Perhaps it does, but the rest of your message should go inside the message body.
You're also missing a close-delimiter
. See the MIME syntax section below.
$body = "This is a multi-part message in MIME format.\r\n";
// text part
$body .= "--$uid\r\n"; // dash-boundary
$body .= "Content-type: text/html; charset=iso-8859-1\r\n";
$body .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$body .= $message;
// file attachment
if (isset ($FILES['attachment'])) {
$file_name = $_FILES['attachment']['name'];
$temp_name = $_FILES['attachment']['tmp_name'];
$file_type = $_FILES['attachment']['type'];
$body .= "\r\n--$uid\r\n"; // delimiter
$body .= "Content-Type: $file_type; name=\"$file_name\"\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
$body .= "Content-Disposition: attachment filename=\"$file_name\"\r\n\r\n";
$body .= $content;
}
$body .= "\r\n--$uid--\r\n"; // close-delimiter
//send the mail
if (mail($to, $subject, $body, $header)) {
/* ... */
Additional notes
$from = $_POST['email'];
$to = 'email@email.com,'.$_POST['email'];
$header = "From: ".$from."\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
if (mail($to, $subject, "", $header)) {
The code above allows the user to send spam or other unwanted email to arbitrary addresses, both through the $to
variable and through the $from
variable (by inserting line-breaks and a Bcc:
header or similar). You should remove $_POST['email']
from $to
, and strip out line-breaks from $from
. I don't know about your Reply-To:
header; $replyto
is undefined.
// if thre is an attachment
$_FILES['attachment']['name'];
This code does nothing (except perhaps generate a notice if there is no attachment).
$extension = substr($base, strlen($base)-4, strlen($base));
This can be simplified as:
$extension = substr($base, -4);
MIME Syntax
This is an excerpt of what the structure of a multi-part message body looks like according to RFC 2046. (BNF syntax, somewhat simplified.)
multipart-body := [preamble CRLF]
dash-boundary CRLF
body-part *encapsulation
close-delimiter
[CRLF epilogue]
dash-boundary := "--" boundary
body-part := MIME-part-headers [CRLF *OCTET]
encapsulation := delimiter
CRLF body-part
delimiter := CRLF dash-boundary
close-delimiter := delimiter "--"
References
- RFC 5322 Internet Message Format
- RFC 2045 (MIME) Part One: Format of Internet Message Bodies
- RFC 2046 (MIME) Part Two: Media Types
Related Topics
Getting Static Property from a Class with Dynamic Class Name in PHP
How to Customize Fos Userbundle Urls
How to Populate HTML Dropdown List with Values from Database
Downloading Attachments to Directory with Imap in PHP, Randomly Works
Php:Binary Image Data, Checking the Image Type
Replace the Variable Price Range by the Chosen Variation Price in Woocommerce 4+
"No Such File or Directory" or "No Such Host Is Known" When Running Migrations
In MVC, Where Do You Draw the Line Between a Controller and Model
PHP Multidimensional Array Get Values
Batch Script to Replace PHP Short Open Tags with <Php
PHP Mail() Attachment Problems
How to Send a Data to a Web Server from Android
Make Switch Use === Comparison Not == Comparison in PHP
How to Redirect to Another Page Using PHP