Download the PHP package phpdot/mail without Composer
On this page you can find all versions of the php package phpdot/mail. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package mail
phpdot/mail
Coroutine-safe transactional email for the PHPdot ecosystem. Compose a message with a fluent, immutable
builder and send it through any transport — SMTP, sendmail, or any Symfony transport — from one injectable
service. Delivery is delegated to the battle-tested symfony/mailer
symfony/mime, fenced entirely behind a single transport boundary; the rest of the package (the builder, the value objects, the receipt) is plain PHPdot code. A fresh transport is built per send, so concurrent coroutines never share a socket under Swoole.
Table of Contents
- Requirements
- Installation
- Usage
- Architecture
- Testing
- License
Requirements
| Requirement | Constraint |
|---|---|
| PHP | >= 8.5 |
symfony/mailer |
^8.0 |
symfony/mime |
^8.0 |
phpdot/container, phpdot/config, and phpdot/package are optional suggestions — install them to
auto-wire the mailer and populate MailConfig from config/mail.php; the attributes are inert at runtime,
so standalone consumers need none of them.
Installation
Usage
Sending
Inject Mailer, compose fluently, and send. Each builder step returns a new Message, so chaining off the
shared mailer never mutates it:
Every message needs a sender: set fromEmail in MailConfig so chains can omit ->from(), or call
->from('[email protected]', 'You') explicitly. cc(), bcc(), replyTo(), attach()/attachData(),
priority(), and header() round out the builder. Header names must be RFC 5322 field names —
printable ASCII without a colon — so ->header("X-Bad\r\nBcc: …", …) throws
InvalidHeaderNameException where it is set instead of injecting lines onto the wire.
Composing without sending
$mail->message() starts a bare Message you can build and pass around; its getters (recipients(),
htmlBody(), attachments(), …) expose the composed state, and a configured base message is a safe
reusable template because every step clones:
Outcomes
send() returns a Receipt (the message id plus the transport's debug transcript — the SMTP session
log when the wire talks SMTP) when the transport accepts the message, and throws
TransportException when it is rejected — every Symfony failure is translated into the package's own
MailException hierarchy, so no Symfony type leaks into your code. The exceptions are shaped for
trace logs: messages are single-line with offending values escaped, and context getters
(getScheme() on TransportException, getHeaderName() on InvalidHeaderNameException) expose the
facts a log line wants — never the DSN, which holds credentials. Accepted is not the same as delivered:
a Receipt means the transport took responsibility, not that the mailbox received it.
Architecture
Mailer is the injected #[Singleton] façade; its builder methods start a fresh immutable Message.
send() hands the message to Transport, which maps it onto a symfony/mime Email via EmailFactory,
builds a one-shot transport from the MailConfig DSN, delivers, and returns a Receipt. Symfony lives
only inside Transport/; Mailbox and Attachment are the immutable value objects.
Testing
License
MIT — see LICENSE.
This repository is a read-only mirror. The canonical source lives in phpdot/monorepo; pull requests and issues are handled there: pulls · issues.