I have a script that collects data and then sends out separate emails to various people. I don’t want the user to wait while the emails are sent. Can I call the email function but have the main script continue without waiting?
You would need to store the information for each email in a queue (database table), then have a scheduled task/cron-job that tests for and sends the emails.
You would need to store the information for each email in a queue (database table), then have a scheduled task/cron-job that tests for and sends the emails.
That’s not entirely true.
There are different methods to achieve non-blocking e-mail sendouts, but it depends on the situation you have.
Furthermore having cron take care of the sendout will cause an unnecessary delay.
Instead of a cronjob the same could as well be achieved via and endless running script. That would avoid the delay but still requires your data to be stored somewhere.
Storing the data isn’t neccessarily faster than sending the mails immediately, so it’s not a big win unless the sending script can as well assemble the mails itself from a minimal dataset.
Php in it’s core cannot run asynchronous jobs, but there are some extensions that can help you with that.
If you have pcntl extension available, forking the process to handle the mails detached would be most elegant, potentially in a detached exec() then if you don’t want your script to wait at all. This way you can also send more than just one email in parallel.
Take a look at pcntl_fork()
If you don’t, you could as well (on linux) run a second script via exec() with a prepended nohup like this example:
exec('nohup php otherscript.php > nohup.out & > /dev/null');
Just for completeness as it is a bit of an overkill for this scenario, the swoole extension has even more powerful ways for running async tasks in php.
Try this works well for me
<?php
//start mail out
?>
<h2 align="center"><font color="green">Please wait while emails to be sent are loaded (This may take a few minutes depending on the number of emails)</font></h2>
<h2 align="center"><font color="blue">Thanks for waiting until the process has completed</font></h2>
<!-- Progress bar holder -->
<div id="progress" style="width:500px;border:1px solid #ccc;"></div>
<!-- Progress information -->
<div id="information" style="width"></div>
<?php
ini_set('post_max_size','40M');
ini_set('upload_max_filesize','4M');
set_time_limit(180); // this will keep the script from stopping if it takes longer then 30 seconds, must have this here
$emailaddress = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$emailsubject = "New messages added to the website";
$fromaddress = "[email protected]";
$i = count($emailaddress);
$z = 0;
echo "<br />";
// here we check how many email address's we have, if its is 0, then we don't start the email function
if ($i != 0)
{// start if
// Lets loop until we reach the count from email address array
$Date = Date("d/m/Y");
// Loop through process
while ($z != $i)
{
// start while
// here we send the email to the varables from above, using the email array increment
$success = mail($emailaddress[$z], $emailsubject, $message, $headers, $fromaddress);
if ($success)
{
//start successful Mail send check file
//write check file
file_put_contents($file, ($Date . PHP_EOL));
file_put_contents('/some_folder/mail_list_addresses_sent.txt', implode("\n", $emailaddress), FILE_APPEND);
//end succesful mail send
}
if (!$success)
{
file_put_contents($file1, ($Date . PHP_EOL));
file_put_contents('/some_folder/mail_list_addresses_failed.txt', implode("\n", $emailaddress), FILE_APPEND);
echo "<br />";
echo "<font color='red'><b>There are email errors, please inform Admin</font></b>";
goto end;
}
// lets echo out that the email was sent
// increment the array one, so we get a new email address from the array
++$z;
//start update progress bar
// Calculate the percentation
$percent = intval($z/$i * 100)."%";
// Javascript for updating the progress bar and information
echo '<script language="javascript">
document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\"> </div>";
</script>';
// This is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
// Send output to browser immediately
flush();
// Sleep one second so we can see the delay
sleep(1);
echo '<script language="javascript">
// document.getElementById("information").innerHTML="'.$i.' emails processed.";
</script>';
//end update progress bar
echo $z . " out of " . $i . " emails sent. <br>";
// end while
}
// Tell user that the process is completed
// Tell user that the process is completed
echo '<script language="javascript">document.getElementById("information").innerHTML="Process completed"</script>';
echo "<br />";
}//end if
else
{//start else
// we echo out that no emails were found in the array and end the script
echo "Warning: No emails in array.";
}
// end else
end: