I have PHP's mail()
using ssmtp which doesn't have a queue/spool, and is synchronous with AWS SES.
I heard I could use SwiftMail to provide a spool, but I couldn't work out a simple recipe to use it like I do currently with mail()
.
I want the least amount of code to provide asynchronous mail. I don't care if the email fails to send, but it would be nice to have a log.
Any simple tips or tricks? Short of running a full blown mail server? I was thinking a sendmail
wrapper might be the answer but I couldn't work out nohup
.
Queue: register the mails to be sent in a queue system (could be done with RabbitMQ, MySQL, redis or anything), then run a cron that consume the queue. Could be done with something as simple as a MySQL table with fields like from , to , message , sent (boolean set to true when you have sent the email).
So yes it's synchronous.
PHP makes use of mail() function to send an email. This function requires three mandatory arguments that specify the recipient's email address, the subject of the the message and the actual message additionally there are other two optional parameters. mail( to, subject, message, headers, parameters );
PHPMailer can use a non-local mail server (SMTP) if you have authentication. Further advantages include: It can print various kinds of error messages in more than 40 languages when it fails to send an email. It has integrated SMTP protocol support and authentication over SSL and TLS.
You have a lot of ways to do this, but handling thread is not necessarily the right choice.
from
, to
, message
, sent
(boolean set to true
when you have sent the email). <?php
class MailSpool
{
public static $mails = [];
public static function addMail($subject, $to, $message)
{
self::$mails[] = [ 'subject' => $subject, 'to' => $to, 'message' => $message ];
}
public static function send()
{
foreach(self::$mails as $mail) {
mail($mail['to'], $mail['subject'], $mail['message']);
}
}
}
//In your script you can call anywhere
MailSpool::addMail('Hello', '[email protected]', 'Hello from the spool');
register_shutdown_function('MailSpool::send');
exit(); // You need to call this to send the response immediately
You must run php-fpm for fastcgi_finish_request to be available.
echo "I get output instantly";
fastcgi_finish_request(); // Close and flush the connection.
sleep(10); // For illustrative purposes. Delete me.
mail("[email protected]", "lol", "Hi");
It's pretty easy queuing up any arbitrary code to processed after finishing the request to the user:
$post_processing = [];
/* your code */
$email = "[email protected]";
$subject = "lol";
$message = "Hi";
$post_processing[] = function() use ($email, $subject, $message) {
mail($email, $subject, $message);
};
echo "Stuff is going to happen.";
/* end */
fastcgi_finish_request();
foreach($post_processing as $function) {
$function();
}
Instantly time-out a curl and let the new request deal with it. I was doing this on shared hosts before it was cool. (it's never cool)
if(!empty($_POST)) {
sleep(10);
mail($_POST['email'], $_POST['subject'], $_POST['message']);
exit(); // Stop so we don't self DDOS.
}
$ch = curl_init("http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'email' => '[email protected]',
'subject' => 'foo',
'message' => 'bar'
]);
curl_exec($ch);
curl_close($ch);
echo "Expect an email in 10 seconds.";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With