vaibhavpandeyvpz/phemail
Composer 安装命令:
composer require 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.
README 文档
README
A pure PHP MIME parser for parsing raw email files (.eml) with full support for multipart messages, nested structures, and RFC 2046 compliance.
Features
- ✅ Pure PHP - No external dependencies required
- ✅ RFC 2046 Compliant - Proper handling of multipart messages with boundaries, preamble, and epilogue
- ✅ Nested Structures - Supports deeply nested multipart messages and message/rfc822 types
- ✅ Header Parsing - Handles folded headers, continuation lines, and header attributes
- ✅ Attachment Detection - Automatically identifies attachments via Content-Disposition header
- ✅ Multiple Input Types - Accepts file paths, arrays, or iterators
- ✅ Immutable Objects - Thread-safe design with immutable message parts
- ✅ PHP 8.2+ - Modern PHP with strict types and latest language features
Requirements
- PHP 8.2 or higher
Installation
composer require vaibhavpandeyvpz/phemail
Basic Usage
Parsing a Simple Email
<?php use Phemail\MessageParser; $parser = new MessageParser(); $message = $parser->parse('path/to/email.eml'); // Get header values echo $message->getHeaderValue('subject'); // "Testing simple email" echo $message->getHeaderValue('from'); // "sender@example.com" echo $message->getHeaderValue('date'); // "Sat, 22 Nov 2008 15:04:59 +1100" // Get header attributes echo $message->getHeaderAttribute('content-type', 'charset'); // "US-ASCII" // Get message content echo $message->getContents();
Parsing from Different Sources
// From file path $message = $parser->parse('/path/to/email.eml'); // From array of lines $lines = file('email.eml', FILE_IGNORE_NEW_LINES); $message = $parser->parse($lines); // From iterator $iterator = new \ArrayIterator($lines); $message = $parser->parse($iterator);
Advanced Usage
Working with Multipart Messages
$message = $parser->parse('multipart.eml'); // Check if message is multipart if ($message->isMultiPart()) { echo "Content-Type: " . $message->getContentType(); // "multipart/mixed" // Get all parts $parts = $message->getParts(); foreach ($parts as $part) { echo "Part: " . $part->getContentType() . "\n"; echo "Content: " . $part->getContents() . "\n"; } }
Extracting Attachments
$message = $parser->parse('email-with-attachments.eml'); // Get all attachments (non-recursive) $attachments = $message->getAttachments(); foreach ($attachments as $attachment) { echo "Filename: " . $attachment->getHeaderAttribute('content-disposition', 'filename') . "\n"; echo "Content-Type: " . $attachment->getContentType() . "\n"; echo "Size: " . strlen($attachment->getContents()) . " bytes\n"; } // Get all attachments recursively (including nested) $allAttachments = $message->getAttachments(true);
Working with Nested Messages
$message = $parser->parse('nested-message.eml'); // Check if a part is a nested message $parts = $message->getParts(); foreach ($parts as $part) { if ($part->isMessage()) { // This is a message/rfc822 part $nestedMessage = $part->getParts()[0]; echo "Nested Subject: " . $nestedMessage->getHeaderValue('subject') . "\n"; } }
Accessing Header Attributes
$message = $parser->parse('email.eml'); // Get a header object $contentType = $message->getHeader('content-type'); // Get header value echo $contentType->getValue(); // "text/plain; charset=UTF-8" // Get all attributes $attributes = $contentType->getAttributes(); // ['charset' => 'UTF-8', 'format' => 'flowed'] // Get specific attribute echo $contentType->getAttribute('charset'); // "UTF-8"
Recursive Part Traversal
$message = $parser->parse('complex-nested.eml'); // Get all parts recursively (including nested parts) $allParts = $message->getParts(true); // Get all attachments recursively (including from nested messages) $allAttachments = $message->getAttachments(true);
API Reference
MessageParser
Methods
parse(string|array|\Iterator $payload, bool $withSubMessage = true): MessagePartInterface- Parses an email from file path, array of lines, or iterator
$withSubMessage: Whether to parse nested message/rfc822 parts recursively
MessagePartInterface
Header Methods
getHeaders(): array<string, HeaderInterface>- Get all headersgetHeader(string $name): ?HeaderInterface- Get a specific header (case-insensitive)getHeaderValue(string $name, ?string $default = null): ?string- Get header valuegetHeaderAttribute(string $header, string $attr, ?string $default = null): ?string- Get header attribute
Content Type Methods
getContentType(): string- Get Content-Type (defaults to "text/plain")isMultiPart(): bool- Check if multipart messageisMessage(): bool- Check if message/rfc822 typeisText(): bool- Check if text/* content type
Content Methods
getContents(): string- Get message body content (preamble for multipart)
Parts and Attachments
getParts(bool $recursive = false): array<MessagePartInterface>- Get nested partsgetAttachments(bool $recursive = false): array<MessagePartInterface>- Get attachments
HeaderInterface
getValue(): ?string- Get header valuegetAttributes(): array<string, string>- Get all attributesgetAttribute(string $name): ?string- Get specific attribute
Examples
Example 1: Simple Text Email
$parser = new MessageParser(); $message = $parser->parse('simple-email.eml'); echo "Subject: " . $message->getHeaderValue('subject') . "\n"; echo "From: " . $message->getHeaderValue('from') . "\n"; echo "Body: " . $message->getContents() . "\n";
Example 2: Multipart with Attachments
$parser = new MessageParser(); $message = $parser->parse('email-with-attachments.eml'); // Get text parts $parts = $message->getParts(); foreach ($parts as $part) { if ($part->isText()) { echo "Text part: " . $part->getContents() . "\n"; } } // Get attachments $attachments = $message->getAttachments(); foreach ($attachments as $attachment) { $filename = $attachment->getHeaderAttribute('content-disposition', 'filename'); file_put_contents($filename, $attachment->getContents()); }
Example 3: Complex Nested Structure
$parser = new MessageParser(); $message = $parser->parse('complex-nested.eml'); // Traverse all parts recursively function processPart($part, $level = 0) { $indent = str_repeat(' ', $level); echo $indent . "Type: " . $part->getContentType() . "\n"; if ($part->isMultiPart()) { foreach ($part->getParts() as $subPart) { processPart($subPart, $level + 1); } } } processPart($message);
Supported Email Formats
- Plain text emails
- Multipart/mixed
- Multipart/alternative
- Multipart/related
- Multipart/signed
- Message/rfc822 (nested messages)
- Headers with folded lines
- Headers with attributes (charset, boundary, filename, etc.)
- Attachments with Content-Disposition
License
This project is licensed under the MIT License. See the LICENSE file for details.
Project Home
vaibhavpandeyvpz/phemail 适用场景与选型建议
vaibhavpandeyvpz/phemail 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 130.09k 次下载、GitHub Stars 达 33, 最近一次更新时间为 2016 年 12 月 07 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「parser」 「email」 「message」 「mime」 「attachment」 「RFC822」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 vaibhavpandeyvpz/phemail 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 vaibhavpandeyvpz/phemail 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 vaibhavpandeyvpz/phemail 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Easy to use SDK with grabber for multiple platforms at once like YouTube, Dailymotion, Facebook and more.
PHP AMQP Binding Library
An MT940 bank statement parser for PHP
Laravel integration for the jsonapi.org parser
Extensible library for building notifications and sending them via different delivery channels.
Email+ extends Kirby's email capabilities by adding support for multiple email services using the same Kirby email API.
统计信息
- 总下载量: 130.09k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 36
- 点击次数: 38
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2016-12-07