PHPackages                             phpdot/mail-parser - 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. [Mail &amp; Notifications](/categories/mail)
4. /
5. phpdot/mail-parser

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

phpdot/mail-parser
==================

Zero-dependency RFC-compliant EML/email parser for PHP 8.2+

v1.0.0(1mo ago)00MITPHPPHP &gt;=8.2

Since Mar 27Pushed 1mo agoCompare

[ Source](https://github.com/phpdot/mail-parser)[ Packagist](https://packagist.org/packages/phpdot/mail-parser)[ RSS](/packages/phpdot-mail-parser/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (1)Versions (2)Used By (0)

PHPdot Mail Parser
==================

[](#phpdot-mail-parser)

Zero-dependency, RFC-compliant EML/email parser for PHP 8.2+.

Parses email messages into clean, structured DTOs with full MIME support, streaming for large files, and built-in security limits.

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

[](#installation)

```
composer require phpdot/mail-parser
```

Requires PHP 8.2+ with `mbstring` and `iconv` extensions (both ship with PHP by default).

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

[](#quick-start)

```
use PHPdot\Mail\Parser\MailParser;

$email = MailParser::parse(file_get_contents('message.eml'));

$email->subject;          // "Hello World"
$email->from->name;       // "John Doe"
$email->from->address;    // "john@example.com"
$email->text;             // plain text body
$email->html;             // HTML body
```

Parsing
-------

[](#parsing)

### From string

[](#from-string)

```
$email = MailParser::parse($rawEmlString);
```

### From file

[](#from-file)

```
$email = MailParser::parse(file_get_contents('/path/to/message.eml'));
```

### From stream (large emails)

[](#from-stream-large-emails)

```
$parser = new MailParser();
$email = $parser->parseStream(fopen('huge-email.eml', 'r'));
```

The streaming parser reads line-by-line without loading the entire email into memory. Attachments are buffered via `php://temp` which auto-spills to disk after 2MB.

### From S3

[](#from-s3)

```
$s3Result = $s3Client->getObject(['Bucket' => 'my-bucket', 'Key' => 'email.eml']);
$stream = $s3Result['Body']->detach();

$parser = new MailParser();
$email = $parser->parseStream($stream);
fclose($stream);
```

Email Properties
----------------

[](#email-properties)

### Addresses

[](#addresses)

```
$email->from;                    // ?Address — primary sender
$email->from->name;              // "John Doe"
$email->from->address;           // "john@example.com"

$email->sender;                  // ?Address — explicit Sender header

$email->to;                      // AddressList
$email->cc;                      // AddressList
$email->bcc;                     // AddressList
$email->replyTo;                 // AddressList

// AddressList is iterable, countable, and supports array access
$email->to[0]->address;         // "jane@example.com"
$email->to->first();            // ?Address
$email->to->isEmpty();          // bool
count($email->to);              // int
foreach ($email->to as $addr) { ... }
```

### Identity &amp; Threading

[](#identity--threading)

```
$email->subject;                 // ?string
$email->messageId;               // ?string — Message-ID without angle brackets
$email->date;                    // ?DateTimeImmutable

$email->inReplyTo;               // ?string — parent Message-ID
$email->references;              // list — full thread chain
```

### Bodies

[](#bodies)

```
$email->text;                    // ?string — plain text body
$email->html;                    // ?string — HTML body
$email->calendar;                // ?string — iCalendar body
```

### Attachments

[](#attachments)

```
$email->attachments;             // AttachmentList

foreach ($email->attachments as $att) {
    $att->filename;              // "report.pdf"
    $att->mimeType;              // "application/pdf"
    $att->disposition;           // "attachment" or "inline"
    $att->size;                  // int (bytes)
    $att->contentId;             // for inline images (cid:)
    $att->content;               // decoded binary string
    $att->nestedEmail;           // ?Email — for message/rfc822 attachments
}

// Filtering
$email->attachments->inline();   // Attachment[] — inline only
$email->attachments->regular();  // Attachment[] — attachment only
$email->attachments->isEmpty();  // bool
$email->attachments->first();   // ?Attachment
```

### Attachment Streaming

[](#attachment-streaming)

For large attachments, use `stream()` to avoid holding content in memory twice:

```
// Pipe directly to S3
$s3Client->putObject([
    'Bucket' => 'attachments',
    'Key' => $att->filename,
    'Body' => $att->stream(),
]);

// Pipe to file
$source = $att->stream();
$dest = fopen('/path/to/file', 'w');
stream_copy_to_stream($source, $dest);
fclose($dest);

// getContent() works for stream-created attachments too
$content = $att->getContent();
```

### Headers

[](#headers)

```
// Simple access — no chains, returns null if missing
$email->header('X-Mailer');              // ?string
$email->header('DKIM-Signature');        // ?string
$email->hasHeader('X-Custom');           // bool
$email->headerAll('Received');           // string[]
```

### Received Headers (Structured)

[](#received-headers-structured)

```
$email->received;                        // list

$hop = $email->received[0];
$hop->from;                              // "mail.example.com"
$hop->fromIp;                            // "209.85.220.41"
$hop->by;                                // "mx.example.com"
$hop->with;                              // "ESMTPS"
$hop->for;                               // "user@example.com"
$hop->date;                              // ?DateTimeImmutable
$hop->raw;                               // original header string
```

### DKIM Signatures (Structured)

[](#dkim-signatures-structured)

```
$email->dkim;                            // list

$sig = $email->dkim[0];
$sig->domain;                            // "example.com"
$sig->selector;                          // "s20210112"
$sig->algorithm;                         // "rsa-sha256"
$sig->headers;                           // "from:to:subject:date"
$sig->signature;                         // base64 signature string
$sig->bodyHash;                          // base64 body hash
$sig->canonicalization;                  // "relaxed/relaxed"
$sig->raw;                               // original header string
```

### SPF Result (Structured)

[](#spf-result-structured)

```
$email->spf;                             // ?SpfResult

$email->spf->result;                     // "pass", "fail", "softfail", etc.
$email->spf->domain;                     // "example.com"
$email->spf->ip;                         // "209.85.220.41"
$email->spf->raw;                        // original header string
```

### Authentication Results (Structured)

[](#authentication-results-structured)

```
$email->authResults;                     // list

$auth = $email->authResults[0];
$auth->server;                           // "mx.google.com"
$auth->dkim;                             // "pass"
$auth->dkimDomain;                       // "example.com"
$auth->spf;                              // "pass"
$auth->spfDomain;                        // "sender@example.com"
$auth->dmarc;                            // "pass"
$auth->dmarcDomain;                      // "example.com"
$auth->raw;                              // original header string
```

Configuration
-------------

[](#configuration)

```
use PHPdot\Mail\Parser\{MailParser, ParserConfig};

$config = new ParserConfig(
    strict: true,                    // throw on RFC violations (default: false)
    maxNestingDepth: 50,             // MIME nesting limit (default: 50)
    maxHeaderSize: 2_097_152,        // header block size limit in bytes (default: 2 MiB)
    maxAttachmentSize: 52_428_800,   // per-attachment limit in bytes (default: 50 MiB)
    maxMessageSize: 104_857_600,     // total message limit in bytes (default: 100 MiB)
    attachmentEncoding: 'string',    // 'string', 'base64', or 'none'
    decodeFlowed: true,              // process format=flowed text (default: true)
);

$email = MailParser::parse($raw, $config);
```

### Strict vs Lenient Mode

[](#strict-vs-lenient-mode)

**Lenient mode** (default): best-effort parsing. Malformed headers are skipped, missing boundaries are detected heuristically, unknown charsets fall back to Windows-1252. Never crashes on real-world email.

**Strict mode**: throws specific exceptions on RFC violations:

- `InvalidHeaderException` — malformed headers
- `InvalidMimeStructureException` — missing boundaries, unknown encodings
- `CharsetConversionException` — unknown character sets
- `SecurityLimitException` — nesting depth, size limits exceeded

RFC Compliance
--------------

[](#rfc-compliance)

RFCCoverageRFC 5322Internet Message Format — headers, folding, addresses, datesRFC 2045MIME Part 1 — Content-Type, Content-Transfer-EncodingRFC 2046MIME Part 2 — multipart/mixed, alternative, related, digestRFC 2047Encoded words in headers (`=?charset?B/Q?text?=`)RFC 2049MIME conformance criteriaRFC 2183Content-Disposition (inline, attachment)RFC 2231Parameter continuations, charset encodingRFC 2392Content-ID / Message-ID URIsRFC 3676format=flowed text/plainRFC 5321Received header parsingRFC 6376DKIM-Signature parsingRFC 6531Internationalized email addressesRFC 6532Internationalized email headers (UTF-8)RFC 7208SPF (Received-SPF) parsingRFC 8601Authentication-Results parsingTesting
-------

[](#testing)

```
composer install
vendor/bin/phpunit
```

295 tests, 929 assertions covering unit tests, integration tests, security limits, malformed email resilience, and streaming parity.

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/62e82421bda4b5d6ba9a47ba6d88caca060dcd0d1a2862f351f3a97657385db0?d=identicon)[phpdot](/maintainers/phpdot)

---

Top Contributors

[![phpdot](https://avatars.githubusercontent.com/u/252500?v=4)](https://github.com/phpdot "phpdot (1 commits)")

---

Tags

parsermimeemailRFC5322emlrfc2046rfc2045rfc2047

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/phpdot-mail-parser/health.svg)

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

###  Alternatives

[zbateson/mail-mime-parser

MIME email message parser

53949.2M79](/packages/zbateson-mail-mime-parser)[vaibhavpandeyvpz/phemail

A pure PHP MIME parser for parsing raw email files (.eml) with full support for multipart messages, nested structures, and RFC 2046 compliance.

33121.7k1](/packages/vaibhavpandeyvpz-phemail)[php-mime-mail-parser/php-mime-mail-parser

A fully tested email parser for PHP 8.0+ (mailparse extension wrapper).

9979.6M27](/packages/php-mime-mail-parser-php-mime-mail-parser)[bashkarev/email

Faster MIME Mail Parser could be used to parse emails in MIME format.

208.8k](/packages/bashkarev-email)[kozz/email-address-parser

Simply parses and autocompletes email addresses

1219.9k](/packages/kozz-email-address-parser)

PHPackages © 2026

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