Email PDF Attachment with PHP Using FPDF
Asked Answered
E

5

19

I want to email a PDF as an attachment that was created using FPDF. My code looks like this, but the attachment never comes through.

<?php
require('lib/fpdf/fpdf.php');

$pdf = new FPDF('P', 'pt', array(500,233));
$pdf->AddFont('Georgiai','','georgiai.php');
$pdf->AddPage();
$pdf->Image('lib/fpdf/giftcertificate.jpg',0,0,500);
$pdf->SetFont('georgiai','',16);
$pdf->Cell(40,10,'Hello World!');
$doc = $pdf->Output('test.pdf', 'S');

//define the receiver of the email
$to = '[email protected]';
//define the subject of the email
$subject = 'Test email with attachment';
//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));
//define the headers we want passed. Note that they are separated with \r\n
$headers = "From: [email protected]\r\nReply-To: [email protected]";
//add boundary string and mime type specification
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents($doc)));
//define the body of the message.
ob_start(); //Turn on output buffering
?>
--PHP-mixed-<?php echo $random_hash; ?> 
Content-Type: multipart/alternative; boundary="PHP-alt-<?php echo $random_hash; ?>"

--PHP-alt-<?php echo $random_hash; ?> 
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hello World!!!
This is simple text email message.

--PHP-alt-<?php echo $random_hash; ?> 
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

<h2>Hello World!</h2>
<p>This is something with <b>HTML</b> formatting.</p>

--PHP-alt-<?php echo $random_hash; ?>--

--PHP-mixed-<?php echo $random_hash; ?> 
Content-Type: application/zip; name="attachment.zip" 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment 

<?php echo $attachment; ?>
--PHP-mixed-<?php echo $random_hash; ?>--

<?php
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();
//send the email
$mail_sent = @mail( $to, $subject, $message, $headers );
//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed"
echo $mail_sent ? "Mail sent" : "Mail failed"; 

?>

Anyone familiar with doing this? I'm hoping to use the PHP mail() function.

Euphonic answered 4/12, 2010 at 11:26 Comment(2)
If it's not for learning purposes, use a PHP mailer library like Swiftmailer. swiftmailer.orgMohn
As Pekka says, Swift Mailer is a much better idea than doing mail with attachments by hand.Brewington
E
30

This ended up working for me:

<?php
require('lib/fpdf/fpdf.php');

$pdf = new FPDF('P', 'pt', array(500,233));
$pdf->AddFont('Georgiai','','georgiai.php');
$pdf->AddPage();
$pdf->Image('lib/fpdf/image.jpg',0,0,500);
$pdf->SetFont('georgiai','',16);
$pdf->Cell(40,10,'Hello World!');

// email stuff (change data below)
$to = "[email protected]"; 
$from = "[email protected]"; 
$subject = "send email with pdf attachment"; 
$message = "<p>Please see the attachment.</p>";

// a random hash will be necessary to send mixed content
$separator = md5(time());

// carriage return type (we use a PHP end of line constant)
$eol = PHP_EOL;

// attachment name
$filename = "test.pdf";

// encode data (puts attachment in proper format)
$pdfdoc = $pdf->Output("", "S");
$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
mail($to, $subject, $body, $headers);

?>
Euphonic answered 5/12, 2010 at 7:29 Comment(2)
thanks, works perfectly in Gmail, but in Outlook the email is a blank page and the message is a 2nd attachment... You know what's causing this?Osteoclasis
I am using this code and occasionally some emails are not received by all recipients. But the Bcc I have set up seems to always come through. I have the code running on Go Daddy shared hosting (Deluxe)... Anybody know why?Rossy
V
24

if you use PHPMailer

$attachment= $pdf->Output('attachment.pdf', 'S');

$mailer->AddStringAttachment($attachment, 'attachment.pdf');

Enjoy

Villareal answered 17/1, 2012 at 19:12 Comment(2)
You saved my day. thanks. I tried base64_encode and chunk_split methods for adding attachment before saw your code. Just clear these methods and everything worked perfect.Officiary
hours and hours searching and here is, nice answer!Phytology
B
3

I think you have a superfluous command there. You are using the string variant of the Output() command:

$doc = $pdf->Output('test.pdf', 'S');

Then you are performing a file_get_contents() on it:

$attachment = chunk_split(base64_encode(file_get_contents($doc)));

It is not a file, it is a file in a string, as file_get_contents() would return if $doc was a filename.

Just reduce that down to:

$attachment = chunk_split(base64_encode($doc));

Then see if any more errors occur.

Brewington answered 4/12, 2010 at 15:14 Comment(2)
I don't get any more errors, but the file is never attached. The email I'm sent has an attachment "noname" at 0kb. Any thoughts on why this might be? Thanks for your help.Euphonic
Getting MIME encoding to work by hand is very difficult, especially when you are adding complicated attachments, I would definitely recommend using a mailing library as mention on your question. Incidentally, you seem to be telling it the filename is attachment.zip and it is a zip file, at no point have you zipped the PDF.Brewington
S
1
Create one pdf file name as testing.pdf  
 <?php 
    //define the receiver of the email 
    $to = '[email protected]'; 

    //define the subject of the email 
    $subject = 'Test email with attachment'; 

    //create a boundary string. It must be unique 
    //so we use the MD5 algorithm to generate a random hash 
    $random_hash = md5(date('r', time())); 

    //define the headers we want passed. Note that they are separated with \r\n 
    $headers = "From: [email protected]\r\nReply-To: [email protected]";

    //add boundary string and mime type specification 
    $headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\""; 

    //read the atachment file contents into a string,
    //encode it with MIME base64,
    //and split it into smaller chunks
    $attachment = chunk_split(base64_encode(file_get_contents('testing.pdf'))); 

    //define the body of the message. 
    ob_start(); //Turn on output buffering 
    ?> 
    --PHP-mixed-<?php echo $random_hash; ?>  
    Content-Type: multipart/alternative; boundary="PHP-alt-<?php echo $random_hash; ?>" 

    --PHP-alt-<?php echo $random_hash; ?>  
    Content-Type: text/plain; charset="iso-8859-1" 
    Content-Transfer-Encoding: 7bit

    Hello World!!! 
    This is simple text email message. 

    --PHP-alt-<?php echo $random_hash; ?>  
    Content-Type: text/html; charset="iso-8859-1" 
    Content-Transfer-Encoding: 7bit

    <h2>Email Pdf File Attachements</h2> 
    <p>This is something with <b>HTML</b> formatting.</p> 

    --PHP-alt-<?php echo $random_hash; ?>-- 

    --PHP-mixed-<?php echo $random_hash; ?>  
    Content-Type: application/pdf; name="attachment.pdf"  
    Content-Transfer-Encoding: base64  
    Content-Disposition: attachment  

    <?php echo $attachment; ?> 
    --PHP-mixed-<?php echo $random_hash; ?>-- 

    <?php 
    //copy current buffer contents into $message variable and delete current output buffer 
    $message = ob_get_clean(); 
    //send the email 
    $mail_sent = @mail( $to, $subject, $message, $headers ); 
    //if the message is sent successfully print "Mail sent". Otherwise print "Mail failed" 
    echo $mail_sent ? "Mail sent" : "Mail failed"; 
?>
Satanic answered 8/8, 2014 at 9:55 Comment(0)
A
0

None of these worked for me...but were close. This is what worked for me and within a WordPress Plugin

function mmd_CreatePDFTest()
{
require(plugin_dir_path( __FILE__ ).'pdf/fpdf.php');    
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont("Arial","B",14);
$pdf->Cell(40,10, "this is a pdf example");
$pdfdoc  = $pdf->Output("", "S");
$content = chunk_split(base64_encode($pdfdoc));

$filename  = "test.pdf";
$file_name = "test.pdf";


$uid       = md5(uniqid(time()));

$mailto = "[email protected]";
$from_mail = "[email protected]";
$replyto = $from_mail = "[email protected]";
$from_name = "YOUR COMPANY NAME | PDF Test";
$subject = "send email with pdf attachment"; 
$message = "<Please see the attachment.";


// header
$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";

// message & attachment
$nmessage = "--".$uid."\r\n";
$nmessage .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$nmessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$nmessage .= $message."\r\n\r\n";
$nmessage .= "--".$uid."\r\n";
$nmessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$nmessage .= "Content-Transfer-Encoding: base64\r\n";
$nmessage .= "Content-Disposition: attachment; filename=\"".$file_name."\"\r\n\r\n";
$nmessage .= $content."\r\n\r\n";
$nmessage .= "--".$uid."--";


$returnpath = "-f" . $from_mail; 
if (mail($mailto, $subject, $nmessage, $header, $returnpath)) 
  return true; 
 else 
  return false;

}  // function mmd_CreatePDFTest()
Artificial answered 16/5, 2022 at 18:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.