PHP mail attachment is blank - php

I got the form to accept an attachment and send the attachment but if it's a doc it's blank:
$fileatt = $_FILES['file']['tmp_name'];
$fileattType = $_FILES['file']['type'];
$fileattName = $_FILES['file']['name'];
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
fclose($file);
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$headers = "from: $email";
$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
$content = "Info about user";
$content = "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$content . "\n\n";
$data = chunk_split(base64_encode($data));
$content .= "--{$mime_boundary}\n" .
"Content-Type: {$fileattType};\n" .
" name=\"{$fileattName}\"\n" .
"Content-Disposition: attachment;\n" .
" filename=\"{$fileattName}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" .
"--{$mime_boundary}--\n";
$send = mail( "user#provider.com", "Form", $content, $headers);
if($send)
header('Location: success page');
else
header('Location: fail page');
The email sends correctly, there is an attachment with the correct name, file type, and file size. when it opens it is empty.
I got the tutorial from sitepoint: http://articles.sitep... ... mail-php/5
I tested the files they provide and the same thing happens. Any ideas would be great. thanks everyone!

Why not use a decent library for sending emails?
I strongly suggest you start using a library for sending emails, it eases the process of writing emails and makes the code a lot more transient.
I can vouch for Swiftmailer, an actively developed library with excellent features.
Especially complicated tasks like attachments, inline images and multiple recipients are implemented easily.

I would strongly recommend using a preexisting tool to send emails, such as Swift. There are a lot of caveats that it will take care of for you, and it's quite easy to use.

Welcome to SO.
This is not a direct answer to your question, but I would recommend you use a ready-made mailing class like PHPMailer. It has all the quirks, encoding and attaching functions already built in, which is much less error-prone than doing it by hand. If you want to go that way, maybe this collection of tutorial links on PHPMailer will help you get started.

Perhaps you could use \r\n instead of those \n\n

Answer with code example is here: http://www.webcheatsheet.com/PHP/send_email_text_html_attachment.php

Related

Sending email attachment using PHP change .doc to .pdf

I created a codes using php its working already with attachment but its only .doc i want to change it to .pdf i tried to change the application/msword to application/pdf and the file name from PO.doc to PO.pdf but its corrupted when i receive it on my email. Can you suggest me what should i do? Below is my codes for that. Thank you.
<?php
$headers = "From:<noreply#example.com>";
$to = 'email#example.com';
$subject = 'Purchase Order';
$txt .="
<html>
<body>
<p><b> PO Number:</b> $purchasenumber</p>
<p><b> Style Code:</b> $styleCode</p>
<p><b> Generic Number:</b> $gennum</p>
<p><b> Vendor Name:</b> $vendname</p>
<p><b> Planned Delivery Date:</b> $pdelivdate</p> <br/> <br/>";
// Always set content-type when sending HTML email
$message = "MIME-Version: 1.0" . "\r\n";
// $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$message .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$fileatt_name2 = "PurchaseOrder.doc";
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// Add the headers for a file attachment
$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
$data2 = chunk_split(base64_encode($txt));
$message = "{$mime_boundary}\n" .
"Content-Type: text/plain; charset=iso-8859-1; format=flowed\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$message .= "{$mime_boundary}\n" .
"Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
// Add file attachment to the message
$message .= "--{$mime_boundary}\n" .
"Content-Type: application/msword;\n" . // {$fileatt_type}
" name=\"{$fileatt_name2}\"\n" .
"Content-Disposition: attachment;\n" .
" filename=\"{$fileatt_name2}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data2 . "\n\n" .
"--{$mime_boundary}--\n";
// Send the message
$send = mail($to, $subject, $message, $headers);
?>
This is not as simple as changing the extension (.doc, .pdf etc.) to convert a file from one type to the other. A more specialized process is needed. What you tried is analogous to taking an apple and dressing it up as a pear. It may look like a pear at first, but when taking a bite you'd discover it is actually an apple.
If you want to convert the .doc to a PDF you can convert it using programs like Microsoft Word (although I'm sure that Libre- or Open-office can do this too). If a more automated manner is desired, consider implementing other solutions like livedocs or phpdocs although the latter is quite pricy.
Depending on the platform (Linux, Windows, OSX) other options might be available as was answered in questions like this one.

Emailing Photos to my Facebook Page

We run the facebook fan page www.facebook.com/GowerLive which features images and updates from our 3 web cameras on the Gower Peninsula; I want to use the feature on Facebook which allows you to email photos directly to your fan page using a unique email address on a CRON job at 8pm each day.
I have tested the email address... That works fine and I can submit images however my PHP Script doesn't display the photos. It will post the subject to facebook but that's it.
Firstly, is this the best way to get the images up to my fan page?
Secondly, am I using the right format of email for this to work as in Multipart Mime Type?
This is my script which I currently have running on a cron
// array with filenames to be sent as attachment
$files = array("public_html/langcam/09.jpg","public_html/langcam/13.jpg","public_html/langcam/16.jpg","public_html/caswellcam/09.jpg","public_html/caswellcam/13.jpg","public_html/caswellcam/16.jpg","public_html/llangcam/09.jpg","public_html/llangcam/13.jpg","public_html/llangcam/16.jpg");
// email fields: to, from, subject, and so on
$to = "uniqueaddress#m.facebook.com";
$from = "email#mysite.com";
$subject = "On ".date("F j, Y")." the wavebuoy at 1pm was ". $waveheightb."ft # ".$seconds."seconds with a ".$windcompass." wind at ".$windspeedb."mph";
$message = "I normally leave this blank";
$headers = "From: $from";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// multipart boundary
$message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";
$message .= "--{$mime_boundary}\n";
// preparing attachments
for($x=0;$x<count($files);$x++){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
"Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
$message .= "--{$mime_boundary}\n";
}
// send
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "Mail sent to $to!";
} else {
echo "Mail could not be sent!";
}
thanks
Lee
Lee,
You might want to look at the Facebook Graph API. I'm not sure if it will work on Fan pages, but see no reason for it not to. Ignore the blog post title and scroll down to the second piece of the article as to how to create an album and upload photos to it.
https://developers.facebook.com/blog/post/498/
The Facebook Graph API page to do with photos is located at the following URL:
http://developers.facebook.com/docs/reference/api/photo/
Or alternatively create an ifttt script on http://ifttt.com as it might be easier.
Jon

PHP mass mail script shows extra file in outlook

I use PHP script to send email with multiple attachments, it works great for gmail, but in Microsoft Outlook i also see blank file ATT00010.txt (random numbers.) as attachment. And when i send email from outlook with multiple attachments as well it does not show no file like this.
I echo'ed output from email script and there is no such file in code. Can someone tell me how to remove this file from outlook?
Email script is below.
// array with filenames to be sent as attachment
$files = array("file_1.ext","file_2.ext","file_3.ext",......);
// email fields: to, from, subject, and so on
$to = "mail#mail.com";
$from = "mail#mail.com";
$subject ="My subject";
$message = "My message";
$headers = "From: $from";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// multipart boundary
$message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";
$message .= "--{$mime_boundary}\n";
// preparing attachments
for($x=0;$x<count($files);$x++){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
"Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
$message .= "--{$mime_boundary}\n";
}
// send
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>mail sent to $to!</p>";
} else {
echo "<p>mail could not be sent!</p>";
}
If you want something that's a little less of a pain to use and send attachments with, try Swift Mailer. (swiftmailer.org) I've been using it in my projects and it works great.
Here's an example:
$message = Swift_Message::newInstance()
->setSubject('Webinar Registration')
->setFrom(array('replyto#example.org' => 'From Name'))
->setTo(array('destination#example.org'))
->setBody($MESSAGE_TEXT)
;
$message->attach(Swift_Attachment::fromPath('SOME_FILE_PATH'));
$transport = Swift_SmtpTransport::newInstance('127.0.0.1', 25);
$mailer = Swift_Mailer::newInstance($transport);
$result = $mailer->send($message);
Just my two cents.
Otherwise, I was going to mention what someone else already beat me to -- check the boundaries.
The last boundary line in a multipart/* message must have -- appended at the end, in addition to what all of the other boundary lines have. A consumer can use that to recognize the end of a message.
Apparently Outlook treats the absence of the correct ending as an indication that the message has been truncated, and then does the best it can to display whatever it did receive.
Its my second account, i actually found solution and don't need no library or class at all although i might turn this into class and add some stuff, its always better to have full understanding of process not just from, to, files etc fields.
Solution is simple here just replace last part with
if ($x == count($files)-1)
$message .= "--{$mime_boundary}--\r\n";
else
$message .= "--{$mime_boundary}\n";
\r is not necessary
if you just put -- it will use it many times inside loop IF checks if this is last loop.

Formatting VCard in PHP

I'm trying to generate a VCard via PHP, and them email it out to the user. I wrote an initial script with hard-coded data, but the end-result will fill in the VCard from MySQL.
When viewing the VCard side-by-side with a legitimate VCard (downloaded and tested from another site) they look pretty much identical, but when I try and import my generated VCard it shows up with no data. Actually, if I open it on my phone, it doesn't even recognize that it is a vcard, and instead just sends me to a broken Google Doc.
I've borrowed some code from wikipedia for formatting the vcard, and everything seems fine. Do you see any errors in my formatting? I've tried different line breaks - to no avail. Ideas?
Here is the code for my generation / mail:
<?php
$content = "BEGIN:VCARD\r";
$content .= "VERSION:3.0\r";
$content .= "CLASS:PUBLIC\r";
$content .= "FN:Joe Wegner\r";
$content .= "N:Wegner;Joe ;;;\r";
$content .= "TITLE:Technology And Systems Administrator\r";
$content .= "ORG:Wegner Design\r";
$content .= "ADR;TYPE=work:;;21 W. 20th St.;Broadview ;IL;60559;\r";
$content .= "EMAIL;TYPE=internet,pref:__munged__#wegnerdesign.com\r";
$content .= "TEL;TYPE=work,voice:__munged__\r";
$content .= "TEL;TYPE=HOME,voice:__munged__\r";
$content .= "URL:http://www.wegnerdesign.com\r";
$content .= "END:VCARD";
mail_attachment("Joe Wegner.vcf", $content, "__munged__#wegnerdesign.com", "__munged__#wegnerdesign.com", "Wegner Design Contacts", "__munged__#wegnerdesign.com", "Joe Wegner's Contact Info", "");
function mail_attachment($filename, $content, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$fileatt_type = "application/octet-stream";
$headers = "FROM: ".$from_mail;
$data = chunk_split(base64_encode($content));
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
$message .= "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type:text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$message . "\n\n";
$message .= "--{$mime_boundary}\n" .
"Content-Type: {$fileatt_type};\n" .
" name=\"{$filename}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" .
"--{$mime_boundary}--\n";
echo "sending message";
mail($mailto, $subject, $message, $headers);
}
?>
Update 1: This makes me more confused, but perhaps it will help you debug. I've downloaded my (bad) generated VCard to my computer, as well as a good VCard downloaded from a different website. As expected, my generated one opens with no data, but the good one works fine. I then created a third empty file with a .vcf extension, and copied the text from my (bad) file into that empty file. I opened that file, and all the data showed perfectly. To test even further, I copied the text from the good VCard file into my bad file, and it still opened with no data. So, it appears it's something about encoding or some other file thing that I don't understand. It's not permissions - that's all identical.
Update 2: I changed my PHP so that it would force me to download the VCard as well as email it. The downloaded file opens perfectly fine, so the error is either happening in how I'm encoding (right word?) the file, or how GMail is interpretting it.
Update 3: Fixed : Figured it out. I'm not sure why this is - because every other tutorial I can find out there says the opposite - but there were a few key changes. First, I changed the encoding on the email from base64 to 8bit, and I changed the attachment content to just be the string passed to the email function (so that it is in 8bit form, not 64). That made the VCard valid and readable on my desktop. To get it to read on my android I had to change the $fileatt_type variable to "text/x-vcard", otherwise Gmail thinks it is a document.
You are missing a \n at the end of each line. If you look at a normal vCard (with notepad++ for example), it has a CR and LF at the end of each line, the one you create only has CR ('\r'). this works for me:
$content = "BEGIN:VCARD\r\n";
$content .= "VERSION:3.0\r\n";
$content .= "CLASS:PUBLIC\r\n";
$content .= "FN:Joe Wegner\r\n";
$content .= "N:Wegner;Joe ;;;\r\n";
$content .= "TITLE:Technology And Systems Administrator\r\n";
$content .= "ORG:Wegner Design\r\n";
$content .= "ADR;TYPE=work:;;21 W. 20th St.;Broadview ;IL;60559;\r\n";
$content .= "EMAIL;TYPE=internet,pref:joe#wegnerdesign.com\r\n";
$content .= "TEL;TYPE=work,voice:7089181512\r\n";
$content .= "TEL;TYPE=HOME,voice:8352355189\r\n";
$content .= "URL:http://www.wegnerdesign.com\r\n";
$content .= "END:VCARD\r\n";
I had to get vcards working in android and iphone recently. I used the following function which is a modified version of the one listed above. This will send vcards that both gmail and mail on the iphone will be able to open. They work in Thunderbird as well.
function mail_attachment($filename, $content, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$fileatt_type = "text/x-vcard";
$headers = "FROM: ".$from_mail;
$data = $content;
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
$message = "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type:text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$message . "\n\n";
$message .= "--{$mime_boundary}\n" .
"Content-Type: {$fileatt_type};\n" .
" name=\"{$filename}\"\n" .
"Content-Transfer-Encoding: 8bit\n" .
"Content-Disposition: attachment;\n" .
" filename=\"{$filename}\"\n\n" .
$data . "\n\n" .
"--{$mime_boundary}--\n";
//echo "sending message";
mail($mailto, $subject, $message, $headers);
}
I wrote a vCard validator based on the RFC which could help. It's not complete, but the cleaned files are at least nicely compatible with the tools and services I've tried (Gmail, gnokii and some others I can't remember). HTH.

Attach file in formmail. (php formmail)

I'm writing a mailform i php for placeing orders, and sense they have to get send a picture to me for the order to work properly, I'd like to be able to attach the file in the formmail. How shuld I do this? I have seen some different sulutions but non that I've complety understand.
You need to set the right mail-headers, and then attach the file by encoding it to whatever form you have declared in the header, like in this snippet:
All you need to do here, is read the file, and encode it (to base64 in this case)
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
fclose($file);
$data = chunk_split(base64_encode($data));
first you'll need a boundary, like a rule to tell where one part stops, and the other begins
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
then set the headers right, to support attachement
$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
then build up your message
$email_message .= "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" . // start text block
"Content-Type:text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$email_content . "\n\n" .
"--{$mime_boundary}\n" . // start attachement
"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" . // this is the file...
"--{$mime_boundary}\n";
and then... sent the message using mail ;-)
mail($email_to, $email_subject, $email_message, $headers)
I would also suggest php_mailer http://sourceforge.net/project/showfiles.php?group_id=26031
Has all of the options you could ever want and lets you build custom length forms without "TOO" much pain
There are also a bunch of tutorials and would gladly send along an example of a project I did recently if you want
$sl="select max(id)AS maxid from photos";
$res=mysql_query($sl);
$rowl=#mysql_fetch_array($res);
$adid=$rowl['maxid'];
$filedir="/photo_gallery/";
$file1=$filedir."img".$adid.$_FILES['myfile']['name'];
//echo $file1;
#move_uploaded_file($_FILES['myfile']['tmp_name'],$file1);
$upd="update photos set photo='".$file1."',Added_date=now() where id=$adid";
//echo $upd;
mysql_query($upd);
#unlink($file1);

Categories