Skip to content

szado/reactphp-mailer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ReactPHP Mailer

A simple, asynchronous email sending library built on top of Symfony Mailer and ReactPHP.

Warning

This library is in early development stage. The API may change in future releases.

Installation

You can install the library using Composer. New to Composer?

composer require shado/reactphp-mailer

Usage

Basic Example

To send your first email, all you need to do is create a Mailer instance with the desired transport DSN.

use Shado\React\Mailer\{ Email, EmailAddress, Factory, MailerException };

$mailer = (new Factory())->create('smtp://user:[email protected]:25');

$email = new Email(
    from: new EmailAddress(address: '[email protected]', name: 'Shado'),
    to: [new EmailAddress('[email protected]')],
    subject: 'Message from ReactPHP Mailer',
    text: 'Hello! This is a test message 😊',
);

try {
    $mailer->send($email);
    echo 'Email sent successfully!';
} catch (MailerException $e) {
    echo "Failed to send email: {$e->getMessage()}";
}

There is also available a promise-based variant of the send() method, if you prefer working with lower-level asynchronous API.

$mailer->sendAsync($email)
    ->then(function () {
        echo 'Email sent successfully!';
    })
    ->catch(function (MailerException $e) {
        echo "Failed to send email: {$e->getMessage()}";
    });

Attachments

You can easily attach local files and embed images in your emails. Attachment files are read by the worker process at send time, so the referenced paths must remain accessible until the email is sent.

Regular attachments are included as separate files and are typically presented to the recipient as downloadable items. In this case, the attachment name is used as the file name shown by the email client.

Inline attachments, on the other hand, are embedded directly into the message content and must be explicitly marked as inline and assigned a unique name. This name is used as a content ID (cid) and allows the attachment to be referenced from HTML content.

use Shado\React\Mailer\{ Email, Attachment };

$email = new Email(
    // ...
    attachments: [
        new Attachment('/path/to/file.pdf'), // Regular attachment
        new Attachment(path: '/path/to/image.jpg', name: 'image@app', inline: true), // Inline attachment
    ],
    html: 'Hello! Here is an embedded image: <img src="cid:image@app" />', // Reference inline attachment by its content ID
);

Please be aware of transport-specific limitations, e.g. SMTP servers may impose restrictions on the maximum email size.

dead event

dead event allows to be notified when the worker process has terminated.

$mailer->on('dead', function () {
    echo "Mailer process has died unexpectedly.\n";
});

Sending Emails at Scale

Under the hood, this library uses a thin abstraction based on a separate process worker. This worker keeps running in the background, so bootstrap time is minimal for subsequent email sends. At the same time, the worker can send only one email at a time. Subsequent send() calls are automatically queued until the previous message is sent.

This is just good enough for most use cases, but if you need to send multiple emails concurrently, consider using the shado/php-resource-pool library, which allows you to create a pool of Mailer instances and manage them efficiently.

use Shado\ResourcePool\{ ResourcePool, FactoryController };
use Shado\React\Mailer\{ Factory };

$factory = new Factory();
$pool = new ResourcePool(
    factory: function (FactoryController $controller) use ($factory) {
        $mailer = $factory->create('smtp://user:[email protected]:25');
        // Detach instance when it dies - the pool will create a new one
        $mailer->on('dead', $controller->detach(...));
        return $mailer;
    },
    limit: 10, // Max 10 concurrent mailers
);

$mailer = $pool->borrow();
// Use $mailer...
$pool->return($mailer);

Supported Transports

Please refer to the Symfony Mailer documentation for details about supported transports.

SMTP, Sendmail and native transports are supported out of the box.

Additionally, you can use third-party transports like (but not limited to) Mailgun, SendGrid and Amazon SES by installing the corresponding Symfony packages.

At the end...

This library was heavily inspired by clue/reactphp-sqlite, so big thanks to the authors for the great work! 💜

  • Run tests: ./vendor/bin/phpunit tests.
  • Feel free to create an issue or submit your PR! 🤗
  • Licence: MIT.

About

A simple, asynchronous email sending library built on top of Symfony Mailer and ReactPHP.

Topics

Resources

License

Stars

Watchers

Forks

Languages