Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mail Mime Parser Laravel Package

zbateson/mail-mime-parser

PSR-compliant, testable MIME email parser for PHP (RFC 822/2822/5322). A standards-based but forgiving alternative to imap* and Pear for reading and inspecting messages, headers, parts, and attachments. Requires PHP 8.1+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require zbateson/mail-mime-parser
    

    Ensure your project uses PHP 8.1+ (required for v4.0+).

  2. Basic Parsing: Parse a raw email string or file handle:

    use ZBateson\MailMimeParser\MailMimeParser;
    
    $parser = new MailMimeParser();
    $message = $parser->parse(file_get_contents('email.eml'), false);
    
  3. First Use Case: Extract core metadata (subject, sender, recipients) and text content:

    echo $message->getSubject(); // "Meeting Notes"
    echo $message->getHeaderValue(\ZBateson\MailMimeParser\Header\HeaderConsts::FROM);
    echo $message->getTextContent(); // Plaintext body
    

Key Entry Points

  • MailMimeParser: Main class for parsing emails.
  • Message: Interface for parsed emails (use Message::from() for static parsing).
  • HeaderConsts: Predefined header constants (e.g., FROM, TO, SUBJECT).

Implementation Patterns

Core Workflows

1. Parsing Emails

  • From Files/Streams:
    $handle = fopen('email.eml', 'r');
    $message = $parser->parse($handle, true); // Auto-closes handle
    
  • From Raw Strings:
    $message = Message::from($rawEmailString, false);
    

2. Extracting Data

  • Headers:
    $fromHeader = $message->getHeader(\ZBateson\MailMimeParser\Header\HeaderConsts::FROM);
    $senderName = $fromHeader->getPersonName(); // "John Doe"
    $senderEmail = $fromHeader->getEmail();     // "john@example.com"
    
  • Attachments:
    foreach ($message->getAttachmentParts() as $attachment) {
        $attachment->saveContent('downloads/' . $attachment->getFileName());
    }
    
  • Multipart Content:
    $htmlPart = $message->getHtmlPart();
    $textPart = $message->getTextPart();
    

3. Handling Encrypted/Signed Emails

Install companion packages:

composer require zbateson/mmp-crypt-smime  # S/MIME
composer require zbateson/mmp-crypt-gpg    # PGP/MIME

The parser automatically decrypts encrypted emails during parsing.

4. Custom Parsing Logic

Override default parsers via PHP-DI:

$parser = new MailMimeParser([
    'parsers' => [
        'custom_header_parser' => \App\CustomHeaderParser::class,
    ],
]);

Integration Tips

Laravel-Specific Patterns

  1. Service Provider Binding:

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton(MailMimeParser::class, function ($app) {
            return new MailMimeParser();
        });
    }
    
  2. Mail Parsing in Controllers:

    use ZBateson\MailMimeParser\MailMimeParser;
    
    public function parseEmail(Request $request)
    {
        $parser = app(MailMimeParser::class);
        $message = $parser->parse($request->file('email')->getRealPath());
    
        return response()->json([
            'subject' => $message->getSubject(),
            'attachments' => count($message->getAttachmentParts()),
        ]);
    }
    
  3. Queueing Parsing Jobs:

    // app/Jobs/ParseEmailJob.php
    public function handle()
    {
        $parser = new MailMimeParser();
        $message = $parser->parse($this->emailContent);
    
        // Process parsed data (e.g., save to DB)
    }
    

Performance Considerations

  • Stream Handling: Use parse($handle, true) to auto-close file handles and avoid leaks.
  • Memory: For large emails, prefer streaming attachments:
    $attachment->getContentStream()->rewind();
    file_put_contents('large-file.pdf', $attachment->getContentStream());
    

Gotchas and Tips

Common Pitfalls

  1. Resource Leaks:

    • Issue: Forgetting to close file handles passed to parse().
    • Fix: Use the second argument (true) to auto-close:
      $parser->parse($handle, true); // Auto-closes
      
  2. Encoding Issues:

    • Issue: Non-ASCII characters in headers/attachments may corrupt.
    • Fix: Use getHeaderValue() with proper charset handling:
      $subject = $message->getSubject(); // Auto-decodes
      
  3. Multipart Parsing:

    • Issue: getHtmlPart()/getTextPart() may return null if no matching part exists.
    • Fix: Check for null and handle gracefully:
      $html = $message->getHtmlPart()?->getContent() ?? 'No HTML content';
      
  4. Custom Headers:

    • Issue: Undocumented headers (e.g., X-Custom-Header) may not parse correctly.
    • Fix: Use getHeader() with raw names:
      $customHeader = $message->getHeader('X-Custom-Header');
      
  5. PHP 8.1+ Requirements:

    • Issue: Older PHP versions will fail with ClassNotFound errors.
    • Fix: Upgrade PHP or use v3.x of the package.

Debugging Tips

  1. Error Handling:

    • Use getErrors() on Message or headers to inspect parsing issues:
      if ($message->getErrors()) {
          foreach ($message->getErrors() as $error) {
              Log::error($error);
          }
      }
      
  2. Logging:

    • Enable logging via MailMimeParser constructor:
      $parser = new MailMimeParser([
          'logger' => new Monolog\Logger('mail_parser'),
      ]);
      
  3. Validation:

    • Validate parsed data with getErrors(true):
      $message->getErrors(true); // Includes additional validation
      

Extension Points

  1. Custom Parsers:

    • Extend AbstractParserService to handle proprietary email formats:
      class CustomParserService extends AbstractParserService
      {
          public function parse($content): IPart
          {
              // Custom logic
          }
      }
      
    • Register via PHP-DI:
      $parser = new MailMimeParser(['parsers' => ['custom' => CustomParserService::class]]);
      
  2. Header Extensions:

    • Create custom headers by extending AbstractHeader:
      class CustomHeader extends AbstractHeader
      {
          protected function parseHeaderValue($value): void
          {
              // Custom parsing logic
          }
      }
      
  3. Attachment Processing:

    • Override AttachmentPart behavior:
      $attachment = $message->getAttachmentPart(0);
      $attachment->setContentDisposition('attachment; filename="custom.name"');
      

Configuration Quirks

  1. Default Parsers:

    • The package includes a "catch-all" parser (NonMimeParserService) for unknown MIME types. To disable:
      $parser = new MailMimeParser(['parsers' => []]); // Empty array
      
  2. Charset Handling:

    • Force charset decoding:
      $parser = new MailMimeParser(['charset' => 'UTF-8']);
      
  3. Deprecations:

    • v4.0+ uses PHP-DI. Older code using global functions (e.g., MailMimeParser::setGlobalLogger) may break. Use constructor injection instead.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope