4

I've written this script that sends customer a receipt of their order, but it has a problem:

It won't wait for the PDF script.

So it simply requires the PDF script, and starts executing it and sends the mail while the PDF script is still working on the PDF. I'm sure that there is a way to delay the email script, but to make thing more complicate:

The whole order.php is executed with jquery ajax call, and the script will wait for the php to finish and then reports browser that request was succeeded. So it could wait over five minutes while the client would be wondering why it's taking so long.

So I need it to wait for the PDF to be created and then send the mail, but it shouldn't leave the client waiting.

Here's my code:

<?php 
    $addid = "orderid.txt";
    $current = file_get_contents($addid) + 1;
    echo $current;
    file_put_contents($addid, $current);
?>
<?php
// Lue tilauksen ID sähköpostia varten
$orderid = "orderid.txt";
$ordernumber = file_get_contents($orderid);

// Kirjoita kuitti
require('receipt.php');
?>
<?php   
//Lähetä tilausvahvistus
require_once('mail/class.phpmailer.php');
$path = "kuitit/kuitti".$orderid.".pdf";
$bodytext = '
Olemme vastaanottaneet tilauksenne '. $ordernumber .'. 
Tilaamanne tuotteet löytyvät liitteestä.'
  ;
$email = new PHPMailer();
$email->From      = 'no-reply@coverlinefilms.fi';
$email->FromName  = 'no-reply@coverlinefilms.fi';
$email->Subject   = 'Olemme vastaanottaneet tilauksenne ' . $ordernumber;
$email->Body      = $bodytext;
$email->AddAddress('christian.nikkanen@gmail.com');
$email->AddAttachment($path, 'kuitti777.pdf');
return $email->Send();

?>

PDF script

1 Answers1

0

In your case (and in most CPU intensive activities) I usually use a queue with two cronjobs: the first will generate the pdf files, and mark them as ready in a database table. The 2nd cronjob will query the database to check if a pdf is in "ready" status and then send the email with the attachment.

Doing this way you'll have in the best scenario an empty queue: all the receipt are sent as soon as they're ready, in the worst case the system will ramp up sending all the emails until the PDF queue is empty.

Hope this approach is clear. You can find some references on PHP daemons (IMHO a better way to manage jobs than a normal PHP script) here.

napolux
  • 15,574
  • 9
  • 51
  • 70
  • Why have two queues - one will suffice? A request to create and email a PDF. – Ed Heal Sep 07 '12 at 15:38
  • You can use a txt file instead of a database or a SQLite db if you have the PHP extension installed. – napolux Sep 07 '12 at 15:40
  • It would be a txt file... But I have no idea what to do, as I'm not too good with PHP. –  Sep 07 '12 at 15:41
  • @EdHeal well, the problem he's spotting is concurrency on the two jobs (pdf generation still running while sending email) the "lock queue" will avoid any problem – napolux Sep 07 '12 at 15:41
  • Yeah, I have the idea of using the txt files, but the term **cronjob** says nothing to me. –  Sep 07 '12 at 15:48
  • @EdHeal - Because you'd essentially just moving his script into a cron job. That won't fix the problem he's having as the email will still send if the PDF takes a while to generate. – andy Sep 07 '12 at 15:53