View on GitHub

zbateson/mail-mime-parser

A PHP email parser

Home - Sponsors - API Documentation - Upgrading to 3.0 - Contributors

Deprecation Notice (since 1.2.1)

getContentResourceHandle, getTextResourceHandle, and getHtmlResourceHandle have all been deprecated due to #106. fread() will only return a single byte of a multibyte char, and so will cause potentially unexpected results/warnings in some cases, and psr7 streams should be used instead. Note that this deprecation doesn’t apply to getBinaryContentResourceHandle or getResourceHandle.

Introduction

MailMimeParser has minimal external dependencies. It requires mbstring to be installed and configured, and two additional composer dependencies that are downloaded and installed via composer: guzzle’s guzzlehttp\psr7 library, and a sister library created to house psr7 stream decorators used by MailMimeParser called zbateson\stream-decorators.

Yes, it’s this easy:

use ZBateson\MailMimeParser\Message;
use GuzzleHttp\Psr7;

$message = Message::from($handleOrStreamOrString);
$subject = $message->getHeaderValue('Subject');
$text = $message->getTextContent();
$html = $message->getHtmlContent();
$from = $message->getHeader('From');
$fromName = $from->getPersonName();
$fromEmail = $from->getEmail();

$to = $message->getHeader('To');
// first email address can be accessed directly
$firstToName = $to->getPersonName();
$firstToEmail = $to->getEmail();

foreach ($to->getAllAddresses() as $addr) {
    $toName = $to->getPersonName();
    $toEmail = $to->getEmail();
}

$attachment = $message->getAttachmentPart(0);
$fname = $attachment->getFilename();
$stream = $attachment->getContentStream();
$attachment->saveContent('destination-file.ext');

There’s no need to worry about the Content-Transfer-Encoding, or how the name in an email address is encoded, or what charset was used.

And, unlike most other available email parsing libraries, MailMimeParser is its own “parser”. It does not use PHP’s imap* functions or the pecl mailparse extension.

There are numerous advantages over other libraries:

Parsing an email

To parse an email using zbateson/mail-mime-parser, pass a ZBateson\MailMimeParser\MailMimeParser object as a dependency to your class, and call parse(). The parse() method accepts a string, resource handle, or Psr7 StreamInterface stream.

Alternatively for procedural/non dependency injected usage, calling Message::from() may be easier. It accepts the same arguments as parse().

use ZBateson\MailMimeParser\MailMimeParser;
use ZBateson\MailMimeParser\Message;

// $resource = fopen('my-file.mime', 'r');
// ...
$parser = new MailMimeParser();

// parse() returns a Message
$message = $parser->parse($resource);

// alternatively:
// $string = 'an email message to load';
$message = Message::from($string);

Message headers

Headers are represented by ZBateson\MailMimeParser\Header\AbstractHeader and sub-classes, depending on the type of header being parsed. In general terms:

To retrieve an AbstractHeader object, call Message::getHeader() from a ZBateson\MailMimeParser\Message object.

// $message = $parser->parse($resource);
// ...

// getHeader('To') returns a ZBateson\MailMimeParser\Header\AddressHeader
$to = $message->getHeader('To');
if ($to->hasAddress('someone@example.com')) {
    // ...
}
// or to loop over AddressPart objects:
foreach ($to->getAddresses() as $address) {
    echo $address->getName() . ' ' . $address->getEmail();
}

For convenience, Message::getHeaderValue() can be used to retrieve the value of a header (for multi-part headers like email addresses, the first part’s value is returned. The value of an address is its email address, not a person’s name if present).

$contentType = $message->getHeaderValue('Content-Type');

In addition, Message::getHeaderParameter() can be used as a convenience method to retrieve the value of a parameter part of a ParameterHeader, for example:

// 3rd argument optionally defines a default return value
$charset = $message->getHeaderParameter(
    'Content-Type',
    'charset',
    'us-ascii'
);
// as opposed to
$parameterHeader = $message->getHeader('Content-Type');

// 2nd argument to getValueFor also optional, defining a default return value
$charset = $parameterHeader->getValueFor('charset', 'us-ascii');

Message parts (text, html and other attachments)

Essentially, the \ZBateson\MailMimeParser\Message object returned is itself a sub-class of \ZBateson\MailMimeParser\Message\Part\MimePart. The difference between them is: MimeParts can only be added to a Message.

Internally, a Message maintains the structure of its parsed parts. Most users will only be interested in text parts (plain or html) and attachments. The following methods help you do just that:

MessagePart (returned by Message::getAttachmentPart()) defines useful stream and content functions, e.g.:

Example:

// $message = $parser->parse($resource);
// ...
$att = $message->getAttachmentPart(0);
echo $att->getContentType();
echo $att->getContent();

Example writing files to disk:

$atts = $message->getAllAttachmentParts();
foreach ($atts as $ind => $part) {
    $filename = $part->getHeaderParameter(
        'Content-Type',
        'name',
        $part->getHeaderParameter(
             'Content-Disposition',
             'filename',
             '__unknown_file_name_' . $ind
        )
    );

    $out = fopen('/path/to/dir/' . $filename, 'w');
    $str = $part->getBinaryContentResourceHandle();
    stream_copy_to_stream($str, $out);
    fclose($str);
    fclose($out);
}

Reading text and html parts

As a convenient way of reading the text and HTML parts of a Message, use Message::getTextStream() and Message::getHtmlStream() or the shortcuts returning strings if you want strings directly Message::getTextContent() and Message::getHtmlContent()

// $message = $parser->parse($resource);
// ...
$txtStream = $message->getTextStream();
echo $txtStream->getContents();
// or if you know you want a string:
echo $message->getTextContent();

$htmlStream = $message->getHtmlStream();
echo $htmlStream->getContents();
// or if you know you want a string:
echo $message->getHtmlContent();

API Documentation

Contributors

Special thanks to our contributors.