PHPackages                             ez-php/mail - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. ez-php/mail

ActiveLibrary[Framework](/categories/framework)

ez-php/mail
===========

Transactional mail module for the ez-php framework — SMTP, log, and null drivers

1.11.1(1mo ago)01101MITPHPPHP ^8.5CI passing

Since Mar 22Pushed 1mo agoCompare

[ Source](https://github.com/ez-php/mail)[ Packagist](https://packagist.org/packages/ez-php/mail)[ Docs](https://github.com/ez-php/mail)[ RSS](/packages/ez-php-mail/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (16)Versions (34)Used By (1)

ez-php/mail
===========

[](#ez-phpmail)

Transactional mail module for the ez-php framework. Delivers outgoing messages via a pluggable driver — SMTP (native PHP, no library required), Log (dev/CI), or Null (silent discard).

---

Installation
------------

[](#installation)

```
composer require ez-php/mail
```

---

Quick Start
-----------

[](#quick-start)

Register the provider in `provider/modules.php`:

```
use EzPhp\Mail\MailServiceProvider;

$app->register(MailServiceProvider::class);
```

Add config values to `config/mail.php`:

```
return [
    'driver'       => env('MAIL_DRIVER', 'null'),
    'host'         => env('MAIL_HOST', '127.0.0.1'),
    'port'         => (int) env('MAIL_PORT', 587),
    'username'     => env('MAIL_USERNAME', ''),
    'password'     => env('MAIL_PASSWORD', ''),
    'encryption'   => env('MAIL_ENCRYPTION', 'tls'),
    'from_address' => env('MAIL_FROM_ADDRESS', ''),
    'from_name'    => env('MAIL_FROM_NAME', ''),
    'log_path'     => env('MAIL_LOG_PATH', ''),
];
```

Send a message:

```
use EzPhp\Mail\Mail;
use EzPhp\Mail\Mailable;

Mail::send(
    (new Mailable())
        ->to('alice@example.com', 'Alice')
        ->subject('Welcome!')
        ->text('Hello Alice, welcome aboard.')
        ->html('Hello Alice, welcome aboard.')
);
```

---

Drivers
-------

[](#drivers)

Driver`MAIL_DRIVER`DescriptionSMTP`smtp`Delivers via a real SMTP server (RFC 5321, pure PHP)Mailgun`mailgun`Mailgun v3 REST API via cURL; no third-party SDKSendGrid`sendgrid`SendGrid v3 Mail Send API via cURL; no third-party SDKLog`log`Writes a summary to a log file; safe for dev/CINull`null`Silently discards every message (default)### SMTP

[](#smtp)

```
MAIL_DRIVER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=user@example.com
MAIL_PASSWORD=secret
MAIL_ENCRYPTION=tls        # tls | ssl | none
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME="My App"
```

Supports TLS via STARTTLS (port 587), implicit SSL (port 465), and plain-text (port 25). Authentication is AUTH LOGIN; omit `MAIL_USERNAME` to skip authentication.

### Mailgun

[](#mailgun)

```
MAIL_DRIVER=mailgun
MAIL_MAILGUN_DOMAIN=mg.example.com
MAIL_MAILGUN_API_KEY=key-xxxxxxxxxxxxxxxxxxxx
MAIL_MAILGUN_REGION=us           # us (default) or eu
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME="My App"
```

Delivers via the Mailgun HTTP API v3. US region uses `api.mailgun.net`; EU region uses `api.eu.mailgun.net`. Attachments are sent as `multipart/form-data`.

### SendGrid

[](#sendgrid)

```
MAIL_DRIVER=sendgrid
MAIL_SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxx
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME="My App"
```

Delivers via the SendGrid v3 Mail Send API. Attachments are base64-encoded and sent inline in the JSON payload.

### Log

[](#log)

```
MAIL_DRIVER=log
MAIL_LOG_PATH=/var/www/html/storage/logs/mail.log
```

When `MAIL_LOG_PATH` is empty, messages are written via `error_log()`.

---

Mailable
--------

[](#mailable)

`Mailable` is a fluent builder that can be used inline or extended per-message type:

```
// Inline
$mail = (new Mailable())
    ->to('bob@example.com', 'Bob')
    ->from('noreply@example.com', 'My App')   // overrides driver default
    ->subject('Your Invoice')
    ->text('Please find your invoice attached.')
    ->html('Please find your invoice attached.')
    ->attach('/path/to/invoice.pdf', 'Invoice-2026-01.pdf');

// Extended
class InvoiceMail extends Mailable
{
    public function __construct(User $user, string $invoicePath)
    {
        $this->to($user->email, $user->name)
             ->subject('Your Invoice')
             ->text('Please find your invoice attached.')
             ->attach($invoicePath);
    }
}
```

### Methods

[](#methods)

MethodDescription`to(string $address, string $name = '')`Set recipient`from(string $address, string $name = '')`Override sender (uses driver default when not called)`subject(string $subject)`Set subject line`text(string $body)`Set plain-text body`html(string $body)`Set HTML body`attach(string $path, string $name = '')`Add file attachmentCombining `text()` and `html()` produces a `multipart/alternative` message. Adding attachments wraps the content in `multipart/mixed`.

---

Static Facade
-------------

[](#static-facade)

`Mail::send(Mailable $mailable)` delegates to the driver bound by `MailServiceProvider`.

In tests, inject a spy driver directly:

```
use EzPhp\Mail\Mail;
use EzPhp\Mail\Mailable;
use EzPhp\Mail\MailerInterface;

// Arrange
$spy = new class implements MailerInterface {
    public array $sent = [];
    public function send(Mailable $mailable): void { $this->sent[] = $mailable; }
};
Mail::setMailer($spy);

// Act
Mail::send((new Mailable())->to('a@b.com')->subject('Hi')->text('body'));

// Assert
assert(count($spy->sent) === 1);

// Teardown
Mail::resetMailer();
```

---

MIME Support
------------

[](#mime-support)

`MimeBuilder` constructs RFC 2822 / MIME messages internally. It handles:

- `text/plain` (quoted-printable)
- `text/html` (quoted-printable)
- `multipart/alternative` (text + HTML)
- `multipart/mixed` (any of the above + attachments)
- RFC 2047 encoding for non-ASCII subject lines and display names
- Base64-encoded attachments with MIME type detection via `mime_content_type()`

---

Queue Integration
-----------------

[](#queue-integration)

Mail delivery is synchronous by default — `Mail::send()` blocks until the driver finishes. To dispatch mail asynchronously, wrap the call in a queue job:

```
use EzPhp\Contracts\JobInterface;
use EzPhp\Mail\Mail;
use EzPhp\Mail\Mailable;

final class SendMailJob implements JobInterface
{
    public function __construct(private readonly Mailable $mailable) {}

    public function handle(): void
    {
        Mail::send($this->mailable);
    }
}

// Dispatch from a controller or service
$queue->push(new SendMailJob(
    (new Mailable())
        ->to($user->email, $user->name)
        ->subject('Welcome!')
        ->text('Hello, welcome aboard.')
));
```

The `Mailable` is serialized with the job. `Mail::send()` inside `handle()` uses whatever driver is registered in the worker process — typically `SmtpDriver` in production and `NullDriver` or `LogDriver` in development.

> **Note:** Queue-backed delivery is an application-layer concern. The `ez-php/mail` package has no dependency on `ez-php/queue`.

---

Local Development with Mailpit
------------------------------

[](#local-development-with-mailpit)

[Mailpit](https://github.com/axllent/mailpit) is a local SMTP mail catcher with a web UI. All outgoing mail is captured and displayed without being delivered to real recipients.

### 1 — Add Mailpit to docker-compose.yml

[](#1--add-mailpit-to-docker-composeyml)

```
services:
  mailpit:
    image: axllent/mailpit
    container_name: my-app-mailpit
    ports:
      - "1025:1025"   # SMTP
      - "8025:8025"   # Web UI
    environment:
      MP_SMTP_AUTH_ACCEPT_ANY: 1
      MP_SMTP_AUTH_ALLOW_INSECURE: 1
```

### 2 — Configure the SMTP driver to point at Mailpit

[](#2--configure-the-smtp-driver-to-point-at-mailpit)

```
MAIL_DRIVER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_ENCRYPTION=none
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_FROM_ADDRESS=dev@example.com
MAIL_FROM_NAME="My App (dev)"
```

### 3 — Open the Mailpit web UI

[](#3--open-the-mailpit-web-ui)

Navigate to `http://localhost:8025` in your browser. Every message sent via `Mail::send()` appears here instantly.

### 4 — SMTP integration tests

[](#4--smtp-integration-tests)

To run the Mailpit smoke tests in `ez-php/mail` itself:

```
MAILPIT_HOST=127.0.0.1 MAILPIT_SMTP_PORT=1025 MAILPIT_API_PORT=8025 \
  vendor/bin/phpunit --group mailpit
```

The three Mailpit tests are skipped automatically when `MAILPIT_HOST` is not set.

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance91

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 89.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

33

Last Release

44d ago

Major Versions

0.9.3 → 1.0.02026-03-24

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/122030400?v=4)[AU9500](/maintainers/AU9500)[@AU9500](https://github.com/AU9500)

---

Top Contributors

[![AU9500](https://avatars.githubusercontent.com/u/122030400?v=4)](https://github.com/AU9500 "AU9500 (97 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (11 commits)")

---

Tags

phpframeworkmailemailsmtpez-php

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ez-php-mail/health.svg)

```
[![Health](https://phpackages.com/badges/ez-php-mail/health.svg)](https://phpackages.com/packages/ez-php-mail)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
