Unable to attach pdf to email in php - php

I've tried to follow the examples given in this forum, like the example given by freestate here - Error with PHP mail(): .
Below is my code copied from his revised example. It emails fine. And an attachment is shown in the email when received. However it cannot be opened and is always 125k in size.
I have verified that a file size is returned with "$file_size = filesize($file);". Also that the "fopen" does open the stream. In fact before I added the Multipart to the header, I could see the content in the body of the text (albeit not readable).
I'm only trying to attach a basic pdf file, on a window's platform (windows 10), Apache 2.4, PHP 5.6.16.0.
What would cause the attachment to fail to attach properly?
emailer('//serverName/path/', 'documentName.pdf');
function eMailer($path, $filename)
{
$eol = PHP_EOL;
$to = "xxxx#yyyyyyyy.com";
$subject = "File Name: ".$filename;
$body = "The this the written content of the body";
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$header = "From: NameOfPerson <their#emailAddress.com>".$eol.
"MIME-Version: 1.0\r\n".
"Content-Type: multipart/mixed; boundary=\"".$uid."\"";
$message = "--".$uid.$eol.
"Content-Type: text/html; charset=ISO-8859-1".$eol.
"Content-Transfer-Encoding: 8bit".$eol.$eol.
$body.$eol.
"--".$uid.$eol.
"Content-Type: application/pdf; name=\"".$filename."\"".$eol.
"Content-Transfer-Encoding: base64".$eol.
"Content-Disposition: attachment; filename=\"".$filename."\"".$eol.
$content.$eol.
"--".$uid."--";
echo (mail($to, $subject, $message, $header))?'success':'failure';
}

So after spending considerable time trying to solve the attachment problem by myself, I decided to use one of the two common packages out there PHPMailer and Swiftmailer. Both seemed pretty good. I work on just one enterprise project and I do not have Composer installed. So I wanted something easy to download and plug into my project manually. After reading the installation instructions for swiftmailer, I decided this would be easy for me to install and use.
These are the steps I took
I downloaded the Swiftmailer zip file from Github
From the unzipped file I copied the "lib" folder right into my project "C:\myproject\lib"
Then I read the usage instructions in the online manual
To use it in my project all I needed to do was include it in my code like this:
function eMailer($path, $filename, $mailto, $subject, $message, $user)
{
$file = $path.$filename;
require_once 'C:\myProject\lib\swift_required.php';
// Create the SMTP configuration
$transport = Swift_SmtpTransport::newInstance("mymail_server_address ie: 192.111.22.33", 25);
$transport->setUsername($user['email']);
$transport->setPassword($user['password']);
// Create the mail transport configuration
$transport = Swift_MailTransport::newInstance();
// Create the message
$message = Swift_Message::newInstance();
$message->setTo(array(
$mailto['email']=> $mailto['name']
));
$message->setSubject($subject);
$message->setBody($message);
$message->setFrom($user['email'], $user['name']);
$message->attach(Swift_Attachment::fromPath($file));
// Send the email
$mailer = Swift_Mailer::newInstance($transport);
$mailer->send($message);
}
This obviously has much more capabilities than I need right now, but if in the future I need a mailer function in another part of my project it's there ready for me to use.

Try below code:
$name = "Name";
$email = "Email Address";
$to = "$name <$email>";
$from = "XYZ";
$subject = "TEST SUBJECT";
$mainMessage = "Hi, here's the file.";
$fileatt = "./test.pdf";
$fileatttype = "application/pdf";
$fileattname = "newname.pdf";
$headers = "From: $from";
// File
$file = fopen ( $fileatt, 'rb' );
$data = fread ( $file, filesize ( $fileatt ) );
fclose ( $file );
// Attach the file
$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/plain; charset=\"iso-8859-1\n" . "Content-Transfer-Encoding: 7bit\n\n" . $mainMessage . "\n\n";
$data = chunk_split ( base64_encode ( $data ) );
$message .= "--{$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 Email
if (mail ( $to, $subject, $message, $headers )) {
echo "The email was sent.";
} else {
echo "There was an error sending the mail.";
}

Related

Php mail not working with more than one recipient

How come this piece of php code doesn't work with multiple recipient ?
It only works if $to has only one adress, like:
$to = 'aa#bb.com';
Edit
It works if email adresses are on the same domain.. For instance, if the website is www.example.com, emails such as xxx#example.com will work but yyy#other.com won't.
Solution
PHPMailer. It gives an easy way to configure SMTP.
Here is the initial code
<?php
//define the receiver of the email
$to = 'aa#bb.com, cc#dd.com, ee#ff.com';
// array with filenames to be sent as attachment
$files = array("a.zip","b.c","a.html");
// email fields: to, from, subject, and so on
$from = "mail#mail.com";
$subject ="My subject";
$message = "My message";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers = "From: $from";
$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>";
}
?>
Here is the final code
// PHPMailer
$mail = new PHPMailer;
// setting up PHPMailer
$mail->isSMTP();
$mail->Host = 'host.com';
$mail->SMTPAuth = false;
$mail->Port = xx;
$mail->setFrom($_POST['email'], $_POST['name']);
$mail->Subject = $_POST['subject'];
$mail->msgHTML($_POST['message']);
foreach($contacts as $contact)
$mail->addAddress($contact['email']);
// If the user has attached some files
foreach ($_FILES as $file)
$mail->addAttachment($file['tmp_name'], basename($file['name']));
$response = array("status" => $mail->send() ? "sent" : "error");
echo json_encode($response);
You need use proper RFC 2822 formating.
Don't use # because you don't know what is the error. If you format mails in format "user#example.com, anotheruser#example.com" it's correct and you need search problem elsewhere.
You can also see example #4 on http://php.net/manual/en/function.mail.php#example-3493 page.
although this is not a direct response to your issue, you could potentially save yourself trouble by using a pre-existing email sending library like either:
phpmailer
https://github.com/PHPMailer/PHPMailer
or simplesmtp
https://bitbucket.org/ghorwood/simplesmtp/

PHPMail sending attachment but they are empty

Basically, I am trying to send a PDF via PHPMail.
the email is sent and I receive it in outlook perfectly. the problem is that the attachment is broken and it doesnt open. I even tried sending a HTML and is also empty.
I tried researching in the forum, tried several "working codes" and other people got it working with this code... I have no clue why is not working for me.
I am using the lastest version of PHPMail 5.2.2
$mail = new PHPMailer();
$staffEmail = "staffemail";
$mail->From = $staffEmail;
$mail->FromName = "name";
$mail->AddAddress('my#email.com');
$mail->AddReplyTo($staffEmail, "name");
$mail->AddAttachment('test.pdf');
$mail->Subject = "PDF file attachment";
$mail->Body = "message!";
$mail->Send();
This custom PHP function will show the (beginning) PHP developer how-to build an e-mail script with attachment function. Please note that inside the mail function is no validation functionality available.
<?php
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." <".$from_mail.">\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";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use different content types here
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
$header .= "--".$uid."--";
if (mail($mailto, $subject, "", $header)) {
echo "mail send ... OK"; // or use booleans here
} else {
echo "mail send ... ERROR!";
}
}
?>
Next we show an example on how-to use this function to send an e-mail message with one attached zip file:
<?php $my_file = "somefile.zip";
$my_path = $_SERVER['DOCUMENT_ROOT']."/your_path_here/";
$my_name = "Olaf Lederer";
$my_mail = "my#mail.com";
$my_replyto = "my_reply_to#mail.net";
$my_subject = "This is a mail with attachment.";
$my_message = "Hallo,\r\ndo you like this script? I hope it will help.\r\n\r\ngr. Olaf";
mail_attachment($my_file, $my_path, "recipient#mail.org", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);
?>
Are you looking for a script to send multiple attachments? Try our mail attachment class script.
If you like to send your websites mail messages via SMTP and Gmail, check our PHPMailer tutorial, too.
I suggest you to upload the file to the server and then attach it to the email. For example, you can use the following steps :
Upload the file
Attach it to the email
Send the email
Delete this temporary file from the server
Try this because I think thats the reason of your poblem.
Just in case: http://php.net/manual/en/features.file-upload.php
Good luck
There can be two problems either path is not correct for attachment or php dont have permission on that folder
this one is working for me trying to send a resume has attachmnet in zend
$mail = new Zend_Mail ();
$mail->setBodyHTML ( stripslashes ($message) );
// add attachment
$fileContents = file_get_contents($attachemnet);
$resume = $mail->createAttachment($fileContents);
$resume->filename = $EmployeeDeatils['resume'];
//$mail->createAttachment($attachemnet);
$mail->setFrom ( $mail_template ['from_email'], $mail_template ['from_caption'] );
$mail->addTo ( $clientemail, $employee_name );
$mail->setSubject ($subject );
try {
$mail->send ();
} catch ( Exception $e ) {
$this->_helper->errorlog ( " Send mail to member with activation link : " . $e->getMessage () );
}
You can try use this function which uses simple mail function of PHP:
function mail_attachment ($from , $to, $subject, $message, $attachment){
$fileatt = $attachment; // Path to the file
$fileatt_type = 'application/octet-stream'; // File Type
$start= strrpos($attachment, '/') == -1 ? strrpos($attachment, '//') : strrpos($attachment, '/')+1;
$fileatt_name = substr($attachment, $start, strlen($attachment)); // Filename that will be used for the file as the attachment
$email_from = $from; // Who the email is from
$email_subject = $subject; // The Subject of the email
$email_txt = $message; // Message that the email has in it
$email_to = $to; // Who the email is to
$headers = "From: ".$email_from;
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
fclose($file);
$msg_txt=""; //\n\nMail created from websiteaddress systems : http://websiteaddress.com
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$headers .= "\nwebsiteaddress-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
$email_txt .= $msg_txt;
$email_message = "This is a multi-part message in websiteaddress format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type:text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n".$email_txt. "\n\n";
$data = chunk_split(base64_encode($data));
$email_message .= "--{$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" .
"--{$mime_boundary}--\n";
$ok = #mail($email_to, $email_subject, $email_message, $headers);
if($ok) {
//echo "Attachment has been mailed !";
//header("Location: index.php");
} else {
die("Sorry but the email could not be sent. Please go back and try again!");
}
}
Hope this will help you.

CSV attachment in PHP

I am trying to send a CSV file as an attachment in PHP and using mail function for attachments. The following code works fine. It successfully attaches the CSV file and sends it to the recipient but the ATTACHED output file (sent in email) comes in text format(.txt). I don't know where i am making mistake and what i need to change in header to retain original CSV file format in attached email.
$path ="/myhost/public_html/csv/";
$file_name = $path."Test";
$file_name.=".csv";
$from = "some#myemail.co.uk";
$to = "other#hisemail.co.uk";
$fat=$file_name;
$subject = $_POST[subject];
// $message = $_POST[message];
//replace \n with <br>
$message = str_replace("\n", "<br>",$message);
//report
echo "<b><font color=#8080FF> From: $from </b><br>";
echo "<b>To: $to </b><br>";
echo "<b>Subject: $subject</b><br><br></font>";
// Obtain file upload variables
$fileatt = $_FILES[$fat]['tmp_name'];
$fileatt_type = $_FILES[$fat]['type'];
$fileatt_name = $_FILES[$fat]['name'];
$headers = "From: $from \n";
// if($_FILES['fileatt']['size'] > 0)
if (file_exists($fat)) {
// Read the file to be attached ('rb' = read binary)
$file = fopen($fat,'rb');
$data = fread($file,filesize($fat));
fclose($file);
// Generate a boundary string
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// Add the headers for a file attachment
$headers .= "MIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
// Add a multipart boundary above the message
$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";
// Base64 encode the file data
$data = chunk_split(base64_encode($data));
// Add file attachment to the message
$message .= "--{$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" .
"--{$mime_boundary}--\n";
} else echo "File error! ";
//send the mail
if(mail($to, $subject, $message,$headers))echo "<b><font color=#FF0000>Message was sent!<b></font>";
else echo "<b><font color=#FF0000>Message error!<b></font>";
I just want to retain original file format in email attachments. Help me please.
I would recommend using a library to handle email attachments. This kind of thing can get complicated quickly and someone else out there has already figured out all the ins and outs of what needs to happen when CSV files are attached. I would use something like http://swiftmailer.org/
You could do all of the code you have above, or something more like...
require_once 'lib/swift_required.php';
$message = Swift_Message::newInstance()
->setSubject('Your subject')
->setFrom(array('john#doe.com' => 'John Doe'))
->setTo(array('receiver#domain.org', 'other#domain.org' => 'A name'))
->setBody('Here is the message itself')
->addPart('<q>Here is the message itself</q>', 'text/html')
->attach(Swift_Attachment::fromPath('my-document.csv'));
Example from: http://swiftmailer.org/docs/messages.html
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use different content types here
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
this might be helpful ?

Attach file from the server into email

can anyone give me some idea how to attach a file from the server and send it as attachment through email??
i have the following code:
<?php
// Read POST request params into global vars
$to = $_POST['to'];
$from = $_POST['from'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// Obtain file upload vars
$fileatt = $_FILES['fileatt']['tmp_name'];
$fileatt_type = $_FILES['fileatt']['type'];
$fileatt_name = $_FILES['fileatt']['name'];
$headers = "From: $from";
if (is_uploaded_file($fileatt)) {
// Read the file to be attached ('rb' = read binary)
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
fclose($file);
// Generate a boundary string
$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}\"";
// Add a multipart boundary above the plain message
$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";
// Base64 encode the file data
// Add file attachment to the message
$message .= "--{$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" . "--{$mime_boundary}--\n";
}
// Send the message
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>Mail sent! Yay PHP!</p>";
} else {
echo "<p>Mail could not be sent. Sorry!</p>";
}
?>
but this code does not attach file from the server.
please help me out.. thanks in advance..!!
One question: Do you want to send e-mails with attachment or do you want to improve your PHP skills with this problem?
If you only want to send mails, have a look at PHPMailer which is very good and easily to handle. For myself I'm using this for years without problems.
For improving your skills: You say that the attachment is encoded in base64, but I cannot find the line where you do something like $data = base64_encode($data); You add the $data of your attachment in plain to the mail.

Sending an email pdf attachment with PHP problems

I am trying to make a script to send emails and attach pdfs or other types of files later on.
I have been following various tutorials and have come to a dead end.
Can anyone see anything wrong with my code? I think i have just been looking at it for far too long.
<?php
include ("../../includes/auth.php");
$id = $_GET['id'];
$date = date('y-m-d h:i:s');
$recipient = $_GET['email'];
$lname = $_GET['lname'];
$fname = $_GET['fname'];
$subject ="Enquiry Form - $date";
//-------------attachment stuff----------
$fileatt = "/test.pdf";
$fileatttype = "application/pdf";
//$fileattname = "newname.pdf";
$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: test person <info#test.co.uk>";
$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/plain; charset=\"iso-8859-1\"\n".
"Content-Transfer-Encoding: 7bit\n\n". $message ."\n\n";
$data = chunk_split(base64_encode($data));
$message .= "–-{$mime_boundary}\n" .
"Content-Type: {$fileatttype};\n" .
" name=\"{$fileattname}\"\n" .
"Content-Disposition: attachment;\n" .
" filename=\"{$fileatt}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" ."--{$mime_boundary}--\n";
$message ."Dear ".$fname." ".$lname." Test message".$date;
echo $recipient."<br />";
echo $subject."<br />";
echo $message."<br />";
echo $headers."<br />";
mail($recipient, $subject, $message, $headers);
include ("../../includes/dbconn.php");
$set_datesent = "UPDATE _leads SET `Covering_letter_sent` = '$date' WHERE `ID` = '$id'";
//echo $set_datesent;
$result = mysql_query ($set_datesent, $connection)
or die ("Failed to perform query : $sql <br />".mysql_error());
?>
I would suggest you use something like the PEAR Mail library. Then sending an attachment becomes as easy and readable as the code below. You'll have to make sure the Mail library is installed, but this is a fairly simple task.
require_once('Mail.php');
require_once('Mail/mime.php');
$text = wordwrap($message, 70); // You'd put the text version of your message here as $message
$mime = new Mail_Mime();
$mime->setTXTBody($text);
$mime->setFrom($name . ' <' . $from_email . '>'); // The sender name and email ID go here
$mime->addAttachment($fpath, $ftype); // File path and type go here
$mime->setSubject($subject); // Subject goes here
$body = $mime->get()
$headers = $mime->headers();
$mail =& Mail::factory('mail');
$mail->send($to_email, $headers, $body); // The recipients email address goes here
unset($mime, $mail);
Additional things also become much easier this way, for example, writing a HTML mail.
I would highly recommend using a library like SwiftMailer. It's free and simplies your life by a lot.
I'd suggest Pear Mail_mime package (http://pear.php.net/package/Mail_Mime/). I once did attachment handling by hand, because i didn't know such library exists (stupid me) and when i figured it out, i immediately got rid of my poorly made script and started to use Mail_mime. It has few glitches, but heck, it's so much easier than code it by hand.

Categories