PHP Email Attachment pdf and docx files don't get sent properly - php

Ok, so while still aware of better solutions, I'm using manual PHP script to send e-mail with an attachment. The only problem I have is that some attachments (PDF, DOCX) are blank when received in an e-mail.
I noticed that when I check $data variable (where the text of the document is stored), in files with extension pdf or docx there are extra characters that are not part of the message in the file. In DOCX file there are some extra characters and in PDF the contents are not displayed at all but some random crap is displayed (encoding?). There should theoretically be a way to attach PDFs and Docx files though.
Not sure how to solve this problem. Would definitely appreciate some help! I'd hate to have to resort to using PHPMailer or SwiftMailer.
Here's my code:
$attachment = $_FILES['uploaded']['tmp_name'];
$att_type = $_FILES['uploaded']['type'];
$att_name = $_FILES['uploaded']['name'];
if (is_uploaded_file($attachment)) {
// Read the file to be attached ('rb' = read binary)
$file = fopen($attachment, 'rb');
$data = fread($file, filesize($attachment));
fclose($file);
// Generate boundary string
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// Add headers for file attachment
$from .= "MIME-Version: 1.0\r\n";
$from .= "Content-Type: multipart/mixed; boundary=\"{$mime_boundary}\"\r\n\r\n";
// Message
$message = "This is a multi-part message in MIME format.\r\n";
$message .= "--{$mime_boundary}\r\n";
$message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n\r\n";
$message .= $msg . "\r\n\r\n";
$data = chunk_split(base64_encode($data));
// Attachment
$message .= "\r\n--{$mime_boundary}\r\n";
$message .= "Content-Type: {$att_type}; name=\"{$att_name}\"\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n";
$message .= "Content-Disposition: attachment; filename=\"{$att_name}\"\r\n\r\n";
$message .= $data . "\r\n";
$message .= "--{$mime_boundary}--\r\n";
} else {
$message = $msg;
}
// Send message
$success = mail($to, $subject, $message, $from);
Is there a way to attach PDF and docx files that I'm missing? Maybe it has something to do with encoding? Or maybe I must read the file differently (if that's the only way). Not sure. Any suggestions?
Edit: .pdf files work now after I added encoding. However .docx files still arrive blank. So the question about docx remains! I edited the code above with the changes I made.
EDIT 2: .docx files work! The file I used to test was incorrect and normal docx file it goes through fine! So problem solved. No need to resort to PHPMailer, although I did try it and it works well. I will either switch to PHPMailer now or use it when I need to add more functionality to the sending mechanism. Otherwise this little script is enough for simple emails with 1 attachment.

Use this, it's much easier, and tested:
http://www.phpclasses.org/package/32-PHP-A-class-for-sending-mime-email-.html

Both files now work fine. PDF files had to have encoding (base64) and after I added that they worked. Docx files always worked, but I used wrong file to test originally. That was causing the problem. So problem solved. There was no need to resort to PHPMailer, however I tried that as well and it works good too.

Related

PHP mail(): PDF won't be decoded from Base64

I'm working on building a mailing script in PHP. I have this code:
$mime_boundary = "---".md5(time());
$message = 'Content-Type: application/pdf;name="datenschutz.pdf";charset=utf-8\n';
$message .= "Content-Transfer-Encoding: base64\n\n";
$fileContents = file_get_contents("/datenschutz.pdf");
$message .= chunk_split(base64_encode($fileContents)) . "\r\n\r\n";
$message .= "--$mime_boundary--";
mail($to, $subject, $message, $headers);
I'm aware that PHPMailer exists, alongside other libraries which would make this easier, but the problem is that I want to sell this software eventually and host it on different servers, so installing a library every time wouldn't be optimal. Therefore, I want to mostly use built-in PHP features.
I do recieve the email, and there is a PDF file attached to it, but neither Browsers nor Adobe Reader can open it.
I personally believe that it is because of the Base64 encoding, since I decoded the file once on a webpage and it worked just fine.
How Am I able to tell the Email program/Adobe Reader to decode the file from base64?
Thanks in advance
Edit: I replaced all different linebreaks with \n\n and redesigned the Content-Type strings so that they are strings with double-quotes. Sadly, it still does not work.

using PHP to return an image in a base64 encoded email

I'm working on an email send and tracking application, but I'm running into a problem that I just can't figure out. I want to us a tracking image in my emails but I'm getting some strange behavior. Currently, I'm sending out emails encoded in base64. In the body of the HTML message I'm using an HTML image tag with a link to a PHP file on my server. That file sends back an image using the following PHP code:
header("Content-Type: image/png");
readfile("full-server-path-to-image.png");
This is where it gets strange. If I view the message in the Outlook email client the image will not display (just shows red "X" image icon). Other normally linked images will display just fine though. If I view the same message in Gmail I am able to see all of the images. It's really weird that the image serves up just fine in some email clients but not all of them.
I noticed this problem started when I changed to encoding my messages in base64. Before I started encoding my messages I was able to view all images in any email client. My gut is telling me this has something to do with the content-encoding-type, but I have no idea how to fix it. Any help would be appreciated!
Here is the PHP code I'm using to send out messages:
$myHTMLmessage = chunk_split(base64_encode('
<html><head></head><body>
<img src="https://www.my-web-site.com/openTrack.php?t={trackerid}"></a>
</body></html>'));
$boundary = uniqid('np');
$to = "somebody-else#another-web-site.com"
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From: somebody#my-web-site.com\r\n";
$headers .= "Content-Type: multipart/alternative;boundary=" . $boundary . "\r\n";
$message = "This is a MIME encoded message.";
$message .= "\r\n\r\n--" . $boundary . "\r\n";
$message .= "Content-Type: text/plain;charset=UTF-8\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n\r\n";
//Plain text body
$message .= "some plain text";
$message .= "\r\n\r\n--" . $boundary . "\r\n";
$message .= "Content-Type: text/html;charset=UTF-8\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n\r\n";
//Html body
$message .= $myHTMLmessage;
$message .= "\r\n\r\n--" . $boundary . "--";
mail($to,$subject,$message,$headers);
Just in case anyone runs into something like this I figured out it all boils down to how email clients encode urls. In my original code I am using a url with 2 parameters inside my image src attribute. Like this:
http://www.my-web-site.com/page.php?pram1=something&pram2=something
When Outlook processes this url it get changed to:
http://www.my-web-site.com/page.php?pram1=something&pram2=something
Other email clients are smart enough to leave the & symbol the way it is without converting it to &
In my live code I needed to $_GET both url parameters and process them. If my script couldn't process both parameters then it wouldn't even get to the line where it would send back an image. The best workaround I could come up with was adding this code in my page.php file:
$pram1 = $_GET['pram1'];
$pram2 = $_GET['pram2'];
if(!isset($pram2)){
$pram2 = $_GET['amp;pram2'];
}
// now regardless of the email client both parameters contain a value to process
if((isset($pram1)) && (isset($pram2))){
header("Content-Type: image/png");
readfile("full-server-path-to-image.png");
}
I know is sounds pretty simple, but I had been scratching my head over this for way too long. Originally, I was convinced it was something to do with how the message was encoded before it was sent out. Never thought it would be Outlook changing my code. On second though Microsoft never likes to make things easy.....never gets old...lol

Sending attachment from file input in form

Hello I have a simple form which collect files. What I mean is that user should be able to put a file into the field and then by submitting the form mail should be sent to the address which is predefined and hardcoded.
here is my form:
<form action='/?page=admin-send' method='post' class='asholder' enctype=\"multipart/form-data\">\n";
<input type='file' name='file' id ='file'/><button name='accept' value='".$ssl->id."' type='submit'>Send</button>
</form>
And now using Php I want to collect this file and put it into email attachment.
$file = $_FILES["file"]["name"];
$filename = basename($file);
$file_size = filesize($file);
$content = chunk_split(base64_encode(file_get_contents($file)));
$uid = md5(uniqid(time()));
$msg = "Hello, this is email with attachment!";
$mail = new HTMLMail();
$mail->from = 'DO NOT REPLY';
$mail->to = 'tstmail#testhost.com';
$mail->subject = 'admin warrning';
$mail->importance = 'Low';
$mail->body = "<P><FONT SIZE=2 FACE=\"Tahoma\">$msg</FONT></P>";
$mail->headers = "From: ".$from."\r\n"
."MIME-Version: 1.0\r\n"
."Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n"
."This is a multi-part message in MIME format.\r\n"
."--".$uid."\r\n"
."Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"
."Content-Transfer-Encoding: base64\r\n"
."Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n"
.$content."\r\n\r\n"
."--".$uid."--";
$mail->send();
And here is the scenario I have problem with:
I put file with name of xyz.pdf which is some document the most important thing is that this document is all right. When I submit my form I am getting the email. Email has attachment which name is xyz.pdf but when I am trying to open this file I am getting the message that the file is borken.
Can anyone point me what I am doing wrong?
I have done the same kind of task, i expect that my answer will help you for sure.
You are letting user 1. upload a file > *2.* process it at your server side using PHP > *3.* and them you are using HTML mail class to send your mail.
The problem is in third step. If the class does not provide you with sufficient function of mail, then it is not worth using. Writing mail HEADERS by yourself poses a lot of complexity and we as a developer should not go that inside.
I recommend you to use PHPMailer 5.1.2, to do this job. This is very simple and is of not more than 80KB (the core files, excluding demos, guides).
With this you can attach multiple files of any mime type(pdf, jpeg, doc etc.) without worrying about headers. This is very simple and i have tested , the attachments are readable at the mailbox.
If you download complete package with demos, you will see how easy it is to implement with PHP.
PHPMailer is the best free php class to send mails on the net(i think) with no bugs.
I haven't used HTML Mail class what you are using, so don't know whether it has functions for attaching files. But writing mail headers is not good. If you are using it by your wish after knowing all this, then i am sorry for posting this answer.

Using mail() to send an attachment AND text/html in an email in PHP4

To make life difficult, the client I'm working for is using a really large yet old system which runs on PHP4.0 and they're not wanting any additional libraries added.
I'm trying to send out an email through PHP with both an attachment and accompanying text/html content but I'm unable to send both in one email.
This sends the attachment:
$headers = "Content-Type: text/csv;\r\n name=\"result.csv\"\r\n Content-Transfer-Encoding: base64\r\n Content-Disposition: attachment\r\n boundary=\"PHP-mixed-".$random_hash."\"";
$output = $attachment;
mail($emailTo, $emailSubject, $output, $headers);
This sends text/html:
$headers = "Content-Type: text/html; charset='iso-8859-1'\r\n";
$output = $emailBody; // $emailBody contains the HTML code.
This sends an attachment containing the text/html along with the attachment contents:
$headers = "Content-Type: text/html; charset='iso-8859-1'\r\n".$emailBody."\r\n";
$headers = "Content-Type: text/csv;\r\n name=\"result.csv\"\r\n Content-Transfer-Encoding: base64\r\n Content-Disposition: attachment\r\n boundary=\"PHP-mixed-".$random_hash."\"";
$output = $attachment;
What I need to know is how can I send an email with text/html in the email body and also add an attachment to it. I'm sure I'm missing something really simple here!
Thanks in advance.
Okay, I've finally cracked it! For reference:
$emailBody .= "<html><body>Blah</body></html>";
$emailSubject = "Subject";
$emailCSV = "\"Col1\", \"Col2\"\r\n"; // etc.
$attachment = $emailCSV;
$boundary = md5(time());
$header = "From: Name <address#address.com>\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed;boundary=\"" . $boundary . "\"\r\n";
$output = "--".$boundary."\r\n";
$output .= "Content-Type: text/csv; name=\"result.csv\";\r\n";
$output .= "Content-Disposition: attachment;\r\n\r\n";
$output .= $attachment."\r\n\r\n";
$output .= "--".$boundary."\r\n";
$output .= "Content-type: text/html; charset=\"utf-8\"\r\n";
$output .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$output .= $emailBody."\r\n\r\n";
$output .= "--".$boundary."--\r\n\r\n";
mail($emailTo, $emailSubject, $output, $header);
Trying to send attachments using the PHP mail() function is an exercise in frustration; put simply, it's just not worth the effort. I would never ever suggest even attempting it, even in current PHP versions. I would always use a library like phpMailer.
I know you said you aren't allowed to use a third party library, but in this case, you would be crazy not to use one. We're talking about the difference between one day of work and a year; it's that big a deal. The PHP mail() function is incredibly difficult to work with, and trying to write code with it to send attachments from scratch will leave you with brittle, bug-ridden code that takes forever to get working reliably in all cases. This is why libraries like phpMailer exist.
So I suggest that regardless of what they want you to do, you should download phpMailer -- the PHP4 version is still available -- and see if it works for you. (The download page even still has the really old versions, so you should be able to go far enough back in time to find one that works with PHP 4.0. It shouldn't take you any time at all to get a simple demo up and running with it. Demonstrate that it works; that may well soften their stance against third party libraries.
(If it doesn't soften their stance, then there's not much hope of this project ever being completed in a sane amount of time. In that case, the best you can do is add a few extra zeros to your quote for the project price and grit your teeth)

Sending mail with a Php with a pdf attachment

I'm trying to send an email from the php mail command. I've been able to what I've tried so far, but can't seem to get it to work with an attachment. I've looked around the web and the best code I've found led me to this:
$fileatt_name = 'JuneFlyer.pdf';
$fileatt_type = 'application/pdf';
$fileatt = 'JuneFlyer.pdf';
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
$data = chunk_split(base64_encode($data));
$MAEmail = "myemail#sbcglobal.net";
mail("$email_address", "$subject", "$message",
"From: ".$MAEmail."\n".
"MIME-Version: 1.0\n".
"Content-type: text/html; charset=iso-8859-1".
"--{$mime_boundary}\n" .
"Content-Type: {$fileatt_type};\n" .
" name=\"{$fileatt_name}\"\n" .
"Content-Disposition: attachment;\n" .
" filename=\"{$fileatt_name}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .$data. "\n\n" );
There are two problems when I do this. First, the contents of the email dissappear.
Second, there is an error on the attachment. "Adobe Reader could not open June_flyer.pdf because it is either not a supported file type or because the file has been damaged (for example it was sent as an email attachment and wasn't correctly decoded)"
Any ideas of how to deal with this?
Thanks,
JB
The very best way how to deal with mail and php is use a reliable well tested library - email with attachments can easily get very nasty. I personally recommend SwiftMailer.
may be problem is within header. if you want to learn the hard way then figure out how you can configure diffrent mimetypes with headers and do the stuff.
or else easy way is use PHPmailer or other email libraries which will do the hard part for you.
One process to learn the correct email format for sending attachments is to try sending yourself an email (with attachment) using Thunderbird, Outlook, etc.
Then view the source of that email. Try copying and pasting that message source into your PHP code (with a little trimming of headers like To and From and Subject that the mail() function already handles) and bada-bing, you have all you need right in front of you.
You can make it dynamic by replacing the chunks of stuff (HTML part, Text part, attachment) with your unique chunks or variables.
Then no fancy library is needed.

Categories