3

I have a small ordering taking app which submits the order to a PHP script by ajax. When the PHP script receives the order it places it in a database, sends an 'OK' message back to the client and then sends a confirmation email to the customer and another to me. The problem is that the client is not seeing the 'OK' (which updates the browser display) for about 15 seconds. If I comment out the email sends, no delay.

... write to database
echo "OK";
mail($semail,'Msg Subject',$message, $header, $bounceto);
mail($semail2,'Msg Subject',$mesage, $header, $bounceto);

Message is only a couple of lines.

Questions:

  • why would there be a delay when calling the mail() function?
  • how can I cause the 'OK' message to be sent without waiting for the PHP script to complete? A flush of some sort I'm guessing.
David G
  • 337
  • 6
  • 17

2 Answers2

3

That's because http://php.net/manual/en/function.mail.php returns boolean value for success or failure and your mail server takes time to process email request.

You can implement some kind of MYSQL queue for emails where you would put emails to be sent and check it with background task (for example using CRON to lauch YourMailQueueProcessingScripts.php that will check if there are any emails to send and perform the sending operation - have in mind that you can run CRON once per minute at most and I don't know if 1 minute delay of sending email is acceptable by you)

Community
  • 1
  • 1
Mark
  • 1,357
  • 16
  • 30
  • Thanks for the info and suggestion. A one minute delay would probably be acceptable. If I can just flush the buffer to the client and then let the PHP chug away it might be better? – David G Mar 16 '17 at 05:31
  • 1
    It should work with http://php.net/manual/en/function.fastcgi-finish-request.php but it requires https://php-fpm.org/ – Mark Mar 16 '17 at 05:39
  • ...and there is http://php.net/register_shutdown_function where you can put mail functions. Still I'd consider them hacks and not proper solutions. Email never was instant so I'd still opt for queue. – Mark Mar 16 '17 at 05:43
  • Well I spoke too soon. It seemed fastcgi_finish_request had solved the problem but in fact it was terminating the PHP script with an error because PHP-FPM isn't loaded (you did flag that). It is a virtual hosting environment so I am not sure if I can (or want to) load PHP-FPM. – David G Mar 18 '17 at 10:49
0

It should work with fastcgi-finish-request.php but it requires PHP FPM

Adding this will output the buffer to the user and cut the connection, the rest of the script will still be executed, but no additional output will be sent, so be sure to output everything before you call fastcgi_finish_request() and thereafter the mail() function

rubo77
  • 19,527
  • 31
  • 134
  • 226