Backend Development 8 min read

Implementing Multithreaded Bulk Email Sending with PHP and Swoole

This article explains how to use the PHP Swoole extension to create asynchronous, coroutine‑based multithreaded email sending, dramatically improving the performance of bulk mail dispatch compared with traditional single‑threaded PHP scripts.

php中文网 Courses
php中文网 Courses
php中文网 Courses
Implementing Multithreaded Bulk Email Sending with PHP and Swoole

In the internet era, bulk email sending is essential for both personal and enterprise workflows, but traditional single‑threaded PHP scripts are slow and inefficient when handling large volumes.

Swoole Overview

Swoole is a C‑based PHP extension that provides multi‑process, multi‑thread, asynchronous I/O, and coroutine capabilities, enabling high‑concurrency, high‑performance server applications. Unlike standard PHP, which processes requests sequentially, Swoole can handle other tasks while waiting for I/O operations.

Implementing Multithreaded Bulk Email Sending

The following code demonstrates how to use Swoole coroutines to send emails concurrently. It defines SMTP server settings, a list of recipient addresses, and creates a coroutine for each email to perform the SMTP handshake, authentication, and message transmission.

<code>// Define email information
$smtp_server = "smtp.xxx.com";
$smtp_username = "[email protected]";
$smtp_password = "xxx";
$smtp_port = 25;
$smtp_ssl = false;
$email_from_address = '[email protected]';
$email_from_name = 'xxx';
$email_subject = 'xxx';
$email_body = 'xxx';

// Define email list
$email_list = array(
    '[email protected]',
    '[email protected]',
    '[email protected]'
);

// Create coroutine
go(function () use ($smtp_server, $smtp_username, $smtp_password, $smtp_port, $smtp_ssl, $email_from_address, $email_from_name, $email_subject, $email_body, $email_list) {
    foreach ($email_list as $email_to_address) {
        $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
        $ret = $client->connect($smtp_server, $smtp_port, $smtp_ssl);
        if (!$ret) { echo "Error: " . $client->errMsg; return; }
        $response = $client->recv();
        if (strpos($response, '220') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send("helo smtpserver\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '250') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send("auth login\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '334') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send(base64_encode($smtp_username) . "\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '334') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send(base64_encode($smtp_password) . "\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '235') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send("mail from:<{$email_from_address}>\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '250') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send("rcpt to:<{$email_to_address}>\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '250') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send("data\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '354') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send("from: {$email_from_name}<{$email_from_address}>\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $ret = $client->send("to: <{$email_to_address}>\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $ret = $client->send("subject: {$email_subject}\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $ret = $client->send("{$email_body}\r\n.\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $response = $client->recv();
        if (strpos($response, '250') === false) { echo "Error: " . $response; $client->close(); return; }
        $ret = $client->send("quit\r\n");
        if (!$ret) { echo "Error: " . $client->errMsg; $client->close(); return; }
        $client->close();
    }
});
</code>

Code Explanation

The script first sets SMTP credentials and a recipient list, then creates a coroutine for each address. Inside each coroutine, it establishes a TCP connection to the SMTP server, performs the SMTP handshake (HELO, AUTH LOGIN), sends the MAIL FROM, RCPT TO, DATA commands, transmits the email headers and body, and finally issues QUIT before closing the connection.

Advantages

Using Swoole with PHP provides an asynchronous I/O model that dramatically improves concurrency, a multithreaded approach that distributes email‑sending tasks across multiple threads, and lightweight coroutines that reduce context‑switch overhead, resulting in faster, more reliable bulk email delivery.

asynchronousmultithreadingphpcoroutineemailSwoole
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.