Search by

erseco / mime-mail-parser

erseco

Parse emails without the mailparse extension

Package info

github.com/erseco/mime-mail-parser

pkg:composer/erseco/mime-mail-parser

Statistics

Installs: 1 386

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0


README

Mime Mail Parser for PHP
Simple, fast, no extensions required

Features | Installation | Credits | Changelog

Packagist Packagist PHP from Packagist Tests Codecov License

Features

Mime Mail Parser has a very simple API to parse emails and their MIME contents. Unlike many other parsers out there, this package does not require the mailparse PHP extension.

The parser intentionally favours practical compatibility with real-world email while keeping bounded resource usage. It does not claim full RFC 5322 conformance.

Standards support

Standard / feature Support
RFC 5322 message headers and body Partial, practical parsing
RFC 2045 MIME structure and transfer encodings Supported for common multipart, base64, and quoted-printable messages
RFC 2047 encoded header words Supported
RFC 2231 extended and continued parameters Supported
Charset conversion for text parts Supported when conversion is available, with built-in ISO-8859-1 and Windows-1252 fallbacks
Nested multipart messages Supported with configurable depth and part limits
Malformed real-world MIME input Best-effort compatibility with explicit safety limits

Get Started

Requirements

  • PHP 8.2+

Installation

To install the package via composer, Run:

composer require erseco/mime-mail-parser

Namespace

The canonical API uses the package namespace:

use Erseco\MimeMailParser\Message;
use Erseco\MimeMailParser\MessagePart;
use Erseco\MimeMailParser\ParserOptions;

Legacy class names such as Erseco\Message, Erseco\MessagePart, and Erseco\ParserOptions remain available as compatibility aliases. They are provided for backwards compatibility only; new code should use the canonical namespace.

Usage

use Erseco\Message;

// Parse a message from a string
$rawEmail = file_get_contents('/path/to/email.eml');
$message = Message::fromString($rawEmail);

// Or parse from a file directly
$message = Message::fromFile('/path/to/email.eml');

// Or parse from any readable PHP stream
$stream = fopen('/path/to/email.eml', 'rb');
$message = Message::fromStream($stream);

// Optional safety limits (defaults keep ordinary mail working)
use Erseco\ParserOptions;

$options = new ParserOptions(
    maxMessageBytes: 10_485_760,   // 10 MiB raw message
    maxParts: 1000,                // leaf MIME parts
    maxDepth: 20,                  // nested multipart depth
    maxHeaders: 500,               // headers per header block
    maxHeaderLineLength: 998,      // bytes per header line
    maxDecodedPartBytes: 10_485_760
);

$message = Message::fromString($rawEmail, false, $options);
// Exceeding a limit throws Erseco\ParserLimitExceededException
// with getLimitName(), getLimitValue(), and getActualValue().

$message->getHeaders();                 // get all headers as array
$message->getHeader('Content-Type');    // get specific header (raw unfolded value)
$message->getContentType();             // 'multipart/mixed; boundary="----=_Part_1_1234567890"'
$message->getFrom();                    // 'Service <service@example.com>'
$message->getTo();                      // 'John Doe <johndoe@example.com>'
$message->getCc();
$message->getBcc();
$message->getMessageId();                // alias of getId()
$message->getSubject();                 // raw subject (may still contain RFC 2047 encoded words)
$message->getDate();                    // DateTime object when the email was sent

// RFC 2047: raw vs decoded headers
// getHeader() / getSubject() keep the raw unfolded value, including encoded-words.
// getDecodedHeader() and the convenience helpers decode B/Q encoded-words to text.
$message->getHeader('Subject');         // '=?UTF-8?B?UmV1bmnDs24gZGUgcHJveWVjdG8=?='
$message->getDecodedHeader('Subject');  // 'Reunión de proyecto'
$message->getDecodedSubject();          // same as getDecodedHeader('Subject')
$message->getDecodedFrom();
$message->getDecodedTo();
$message->getDecodedReplyTo();
$message->getDecodedCc();
$message->getDecodedBcc();

// Structured mailbox addresses
$message->getFromAddresses();            // list<Address>
$message->getToAddresses();
$message->getCcAddresses();
$message->getBccAddresses();
$message->getReplyToAddresses();


$message->getParts();       // Returns array of MessagePart objects
$message->getHtmlPart();    // Returns MessagePart with HTML content
$message->getTextPart();    // Returns MessagePart with Text content
$message->getAttachments();     // Returns array of attachment MessageParts
$message->getAttachedMessages(); // Returns parsed message/rfc822 attachments

// Working with message parts
$parts = $message->getParts();
$firstPart = $parts[0];

$firstPart->getHeaders();                 // array of all headers for this part
$firstPart->getHeader('Content-Type');    // get specific header
$firstPart->getContentType();             // 'text/html; charset="utf-8"'
$firstPart->getMediaType();                // 'text/html'
$firstPart->getContentTypeParameters();    // ['charset' => 'utf-8']
$firstPart->getDisposition();              // 'attachment', 'inline', or null
$firstPart->getDispositionParameters();    // decoded RFC 2231 parameters
$firstPart->getContent();                 // transfer-decoded content (no charset conversion)
$firstPart->getContentAsUtf8();           // text/* parts converted to UTF-8 when possible
$firstPart->getCharset();                 // charset from Content-Type, or null
$firstPart->isHtml();                     // true if it's an HTML part

$firstPart->isText();                     // true if it's a text part
$firstPart->isAttachment();               // true if it's an attachment
$firstPart->isMessage();                  // true for message/rfc822
$firstPart->getMessage();                 // nested Message or null
$firstPart->getFilename();                // name of the file if attachment
                                          // supports filename=, filename*=, and RFC 2231
                                          // continuations (filename*0*=, filename*1*=, …)
$firstPart->getSize();                    // size of content in bytes

Credits

License

The MIT License (MIT). Please see License File for more information.