pralhadstha/php-mailer-gateways

Framework-agnostic PHP mailer with pluggable providers (SMTP, SparkPost, Amazon SES, Mailgun and more) on top of Symfony Mailer.

Maintainers

Package info

github.com/pralhadstha/php-mailer-gateways

pkg:composer/pralhadstha/php-mailer-gateways

Transparency log

Statistics

Installs: 34

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.2 2026-08-07 17:13 UTC

This package is auto-updated.

Last update: 2026-08-07 17:19:30 UTC


README

Framework-agnostic PHP mailer with pluggable providers (SMTP, SparkPost, Amazon SES, Mailgun and more), built on top of Symfony Mailer. Works in any PHP frameworks or plain PHP.

use Pralhadstha\Mail\Mail;

Mail::configure([
    'default' => 'sparkpost',
    'mailers' => [
        'sparkpost' => ['provider' => 'sparkpost', 'api_key' => getenv('SPARKPOST_API_KEY')],
        'ses' => ['provider' => 'ses', 'access_key' => '...', 'secret_key' => '...'],
    ],
]);

Then send from anywhere in the app:

use Pralhadstha\Mail\Mail;
use Symfony\Component\Mime\Email;

$email = (new Email())
    ->from('postmaster@example.com')
    ->to('user@example.com')
    ->subject('Hello')
    ->text('Hi there');

Mail::send($email);                 // uses the "default" mailer
Mail::send($email, mailer: 'ses');  // or a specific named mailer

Messages are built with Symfony's own Symfony\Component\Mime\Email, so there's no separate message DTO to learn.

If you'd rather build and hold onto a MailerInterface yourself instead of going through the static Mail facade, use MailerFactory directly — see "Without the Mail facade" below.

Requirements

  • PHP >= 8.1
  • symfony/mailer — installed automatically, covers smtp, null, and array.
  • Each other provider needs its own bridge installed alongside this package — see the table below. Nothing is pulled in for a provider you don't use.

Installation

composer require pralhadstha/php-mailer-gateways

Then add the bridge for the provider(s) you actually use:

Provider Install command
smtp (nothing extra needed)
ses composer require symfony/amazon-mailer
mailgun composer require symfony/mailgun-mailer
sparkpost composer require gam6itko/sparkpost-mailer

Per-provider config

Each entry under mailers in Mail::configure() is a provider key plus that provider's config. The same array shape works with MailerFactory::create() directly (see below).

// SMTP
['provider' => 'smtp', 'host' => 'smtp.example.com', 'port' => 587, 'username' => '...', 'password' => '...']

// Amazon SES (mode: api [default] | https | smtp)
['provider' => 'ses', 'access_key' => 'AKIA...', 'secret_key' => '...', 'region' => 'us-east-1']

// Mailgun (mode: api [default] | https | smtp)
['provider' => 'mailgun', 'key' => '...', 'domain' => 'mg.example.com', 'region' => 'eu']

// SparkPost (mode: api [default] | smtp)
['provider' => 'sparkpost', 'api_key' => '...', 'region' => 'eu']

// Disable sending
['provider' => 'null']

// In-memory, for tests - see "Testing your own code" below
['provider' => 'array']

region is optional for ses/mailgun/sparkpost. port is optional for smtp.

Testing your own code

Use the array provider to capture sent mail in memory instead of delivering it. Mail::transport() returns the raw transport behind a configured mailer:

Mail::configure(['default' => 'test', 'mailers' => ['test' => ['provider' => 'array']]]);

Mail::send($email);

$transport = Mail::transport(); // ArrayTransport
$transport->count();            // 1
$transport->lastMessage();      // the Email instance

Without the Mail facade

For cases where you'd rather hold onto a MailerInterface yourself (e.g. injecting it through your framework's container) instead of the static facade:

use Pralhadstha\Mail\MailerFactory;

$mailer = (new MailerFactory())->create([
    'provider' => 'sparkpost',
    'api_key' => getenv('SPARKPOST_API_KEY'),
]);

$mailer->send($email);

Adding a provider

Implement Pralhadstha\Mail\Provider\ProviderInterface::dsn(array $config): string to build the Symfony Mailer DSN from your own config keys, then register it on the factory used by Mail::configure() or built directly:

$factory = new MailerFactory();
$factory->registerProvider('postmark', new PostmarkProvider());

Mail::configure([...], $factory);

If the provider's transport factory isn't one of Symfony's own bridges, also register it so Transport::fromString() can resolve the DSN:

$factory->registerFactory(new PostmarkTransportFactory());

Framework implementation

See FRAMEWORKS.md for how to wire it into each one, and the examples/ directory for full runnable examples.

Development

composer install
composer test
composer stan    
composer cs && composer csfix