Sending emails asynchronously

I want to ensure that my web application can send out emails asynchronously, allowing other processes to run simultaneously without interruption.
Kindly guide me on how I can do this with Zend

Hey Hanako,

PHP does not support multithreading by default. Nevertheless, you can realise your project with PHP. Here are some approaches …

CLI and cron jobs

Just write a PHP script that can be executed via CLI. Laminas uses its own cli command package, which extends symfony-command. You can write your own command and execute it in short intervals via cron job. This kind of execution would kind of run asynchronously, since you can execute other logic in parallel.

Use modern extensions

Modern PHP extensions like Swoole, ReactPHP, etc. enable concurrent services. Sure, it 's yet another dependency. But they 're doing a good job when it comes to handle async requests.

PHP 's own Fiber

Since PHP 8.1 the Fiber class is available with native PHP. Yes, it’s all a bit complicated. But it could also be used to represent roughly competing behaviour.

The pthreads PHP extension

Do NOT use this extension anymore. This extension is outdated and unmaintained.

1 Like

In Zend, there’s no built-in support for asynchronous operations like sending emails asynchronously out of the box, since PHP is synchronous by nature. However, you can simulate this behavior by dispatching an email job to a queue system and then processing it with a background worker. I suggest using Mailtrap as a mail server for testing. It has an in-built code integration with Laminas.

use Zend\Mail\Message;
use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;

// Configure the SMTP server
$smtpOptions = new SmtpOptions([
    'name'              => 'localhost',
    'host'              => 'smtp.mailtrap.io',
    'port'              => 587,
    // Notice that zend-mail sets the connection class to 'login' by default
    'connection_class'  => 'login', 
    'connection_config' => [
        'username' => 'your_mailtrap_username',
        'password' => 'your_mailtrap_password',
        'ssl'      => 'tls',
    ],
]);

// Create a new message
$message = new Message();
$message->setEncoding('UTF-8');
$message->addTo($recipient);
$message->addFrom('noreply@example.com');
$message->setSubject($subject);
$message->setBody($body);

// Send the email via SMTP
$transport = new SmtpTransport();
$transport->setOptions($smtpOptions);
$transport->send($message);

As an alternative, I suggest Mailpit, which is a free, open source, single binary (written in GO) that runs locally, catches your email, and display them instantly in a webmail. It also offers some HTML/CSS compatibility checks. And all of it can run offline.