5

I know how to generate PDF using mPDF library and send it as attachment using PHPMailer - something like this:

...
$emailAttachment = $mpdf->Output('file.pdf', 'S');
$mail = new PHPMailer();
$mail->AddStringAttachment($emailAttachment, 'file.pdf', 'base64', 'application/pdf');
...

But what if I generate PDF in separate PHP file (that should not be modified) - like this - invoice.php:

...
$mpdf = new mPDF();
$mpdf->WriteHTML($html);
$mpdf->Output();
exit;

How can I attach this dynamically created PDF file using PHPMailer? I tried this:

$mail = new PHPMailer();
...
$mail->addStringAttachment(file_get_contents('invoice.php'), 'invoice.pdf',  'base64', 'application/pdf');
$mail->send();

Email is sent with correct content but PDF attachment is corrupted and thus cannot be displayed. How to encode it correctly? I tried few other ways but file is corrupted or is not attached at all (in one case, whole email body was blank).

Thank you for your help in advance! :)

Ján Janočko
  • 460
  • 2
  • 7
  • 19
  • you need to insure that your php file is returning a PDF string – Adhan Timothy Younes Jun 07 '17 at 08:42
  • When you're attaching a file, use `addAttachment` rather than `addStringAttachment`; either way, check the return value from the call to be sure it worked. – Synchro Jun 07 '17 at 10:08
  • @AdhanTimothyYounes - When I put invoice.php url in my browser, PDF is successfully displayed... so it is ok. – Ján Janočko Jun 08 '17 at 05:47
  • @Synchro: I tried `addAttachment` as first - but no attachment was added at all. Then I found that this works only for local files (not PHP processed) and there should be used `addStringAttachment` instead. – Ján Janočko Jun 08 '17 at 05:49

1 Answers1

8

The problem is that you're using file_get_contents incorrectly; as you've used it, it will fetch the contents of include.php, not the results of its execution. You need to expand it to a full URL in order to have it fetched that way, though I would advise not doing that. Have the script generate a PDF file and then load that, using the file output option of mpdf:

$mpdf = new mPDF();
$mpdf->WriteHTML($html);
$mpdf->Output('/path/to/files/invoice.pdf', 'F');

Then run that script and attach the resulting file from PHPMailer (and delete the file afterwards):

include 'invoice.php';
$mail = new PHPMailer();
...
$mail->addAttachment('/path/to/files/doc.pdf');
$mail->send();
unlink('/path/to/files/invoice.pdf');

You could skip the external file approach by using the "return a string" output mode (S) of the Output method and returning the string from the included file:

$mpdf = new mPDF();
$mpdf->WriteHTML($html);
return $mpdf->Output('invoice.pdf', 'S');

and then:

$pdf = include 'invoice.php';
$mail = new PHPMailer();
...
$mail->addStringAttachment($pdf, 'invoice.pdf');
$mail->send();
Synchro
  • 35,538
  • 15
  • 81
  • 104
  • Thanks, I ended up generating file, attaching and then unlinking it. Originally I wanted to avoid editing of PDF generating script and just use it as it is. So you say, that using full URL would do the job? It makes sense... Why would you not advise doing it this way? – Ján Janočko Jun 09 '17 at 05:42
  • 1
    Because it adds a lot of overhead, increases attack surface on your app, makes the running of your code involve the web server unnecessarily. Passing the string directly will be the fastest and most efficient way. – Synchro Jun 09 '17 at 06:52