yarri/email-parser
Composer 安装命令:
composer require yarri/email-parser
包简介
Parses raw MIME email messages from strings or files into structured PHP objects, with automatic UTF-8 conversion, attachment detection, and built-in caching
README 文档
README
Parses raw MIME email messages from strings or files into structured PHP objects, with automatic UTF-8 conversion, attachment detection, and built-in caching.
EmailParser tries to simplify some of the pains in the email parsing process:
- All headers, text/plain and text/html parts (which are not attachments) and filenames of attachments are converted into UTF-8 encoding.
- In these components, illegal UTF-8 characters are replaced.
- Attachment filenames are properly sanitized.
- Email can be parsed by its source or by its filename.
- The email source file can be gzipped.
- EmailParser itself determines mime types of all attachments found in the message.
- An email sent as an attachment in another email can be easily accessed by calling $part->getAttachedEmail().
- A caching mechanism is built-in in EmailParser.
- Contents of attachments can be accessed via StringBuffer which has a positive impact on memory consumption.
Usage
$parser = new \Yarri\EmailParser();
// Parsing email
$email = $parser->parse($email_content);
// or
$email = $parser->parseFile("/path/to/email.eml");
// or
$email = $parser->parseFile("/path/to/email.eml.gz");
// Getting headers
$email->getSubject();
$email->getFrom(); // e.g. "John Doe <john@example.com>"
$email->getFromEmail(); // e.g. "john@example.com"
$email->getFromName(); // e.g. "John Doe"
$email->getTo();
$email->getCc();
$email->getBcc();
$email->getDate(); // returns date in the ISO format (YYYY-mm-dd H:i:s) in the current timezone (set via date_default_timezone_set()); e.g. "2025-05-25 12:40:22"
$email->getHeader("Date"); // e.g. "Sun, 25 May 2025 06:37:33 +0200 (CEST)"
$email->getHeader("Return-Path");
$email->getHeader("Subject"); // same as $email->getSubject()
$email->getHeader("Received"); // returns string
$email->getHeader("Received",["as_array" => true]); // returns array of strings
$email->hasAttachment(); // true or false
$email->getSmtpRelayIps(); // e.g ["78.45.42.91","209.85.128.53"]
// Displaying the message
$part = $email->getFirstReadablePart();
// or
$part = $email->getFirstReadablePart(["prefer_html" => true]);
//
header(sprintf(
"Content-Type: %s; charset=%s",
$part->getMimeType(), // "text/plain" or "text/html"
$part->getCharset() // always "UTF-8"
));
echo $part->getContent();
// Traversing email structure
$parts = $email->getParts();
foreach($parts as $part){
$id = $part->getId(); // 1,2,3...
$level = $part->getLevel(); // 1,2,3..
$padding = str_repeat(" ",$level); // " "," "," "...
$mime_type = $part->getMimeType();
if($part->hasContent()){
$content_info = $part->getSize()." bytes";
if($part->getFilename()){
$content_info .= ", ".$part->getFilename();
}
}else{
$content_info = "no content";
}
echo "$id.$padding$mime_type ($content_info)\n";
}
// Something like this can be printed:
/*
1. multipart/related (no content)
2. multipart/alternative (no content)
3. text/plain (55 bytes)
4. text/html (107 bytes)
5. image/png (11462 bytes, dungeon-master.png)
6. image/jpeg (9123 bytes, pigeon.jpg)
// */
// Navigating part relationships
$part = $email->getPartById(4); // text/html
$parent = $part->getParentPart(); // multipart/alternative
$siblings = $parent->getChildParts(); // [text/plain, text/html]
// Getting parts by id or Content-Id
$part = $email->getPartById(5);
$part->isAttachment(); // true
$part->getMimeType(); // "image/png"
$part->getContent(); // binary content
// Embedded images can be looked up by their Content-Id
$part = $email->getPartByContentId("unique-image-001@example.com");
$part->getContentId(); // "unique-image-001@example.com"
$part->getMimeType(); // "image/png"
$part->isAttachment(); // false (inline image inside multipart/related)
// Email sent as an attachment
$email = $parser->parseFile("/path/to/email_with_message_rfc822_part.eml");
$parts = $email->getParts();
$part_message_rfc822 = $parts[2]; // for instance the 3rd part is message/rfc822, i.e. an attached email
$part_message_rfc822->isAttachedEmail(); // true
$attached_email = $part_message_rfc822->getAttachedEmail();
$attached_email->getSubject();
$attached_email->getFrom();
$attached_email->getTo();
$attached_email_parts = $attached_email->getParts();
// etc.
// Caching mechanism
// (you are responsible for providing specific cache path for every email you want to parse)
$email = $parser->parse($email_1_content,"/path/to/cache/for_email_1/");
// or
$email = $parser->parseFile("/path/to/email_2.eml","/path/to/cache/for_email_2/");
// or
$email = $parser->parseFile("/path/to/email_3.eml.gz","/path/to/cache/for_email_3/");
// Displaying attachment via StringBuffer which is memory more efficient
// (only takes effect when caching is active)
header(sprintf('Content-Type: %s', $part->getMimeType()));
header(sprintf('Content-Disposition: attachment; filename="%s"', $part->getFilename()));
$buffer = $part->getContentBuffer();
$buffer->printOut();
Installation
Just use the Composer:
composer require yarri/email-parser
Testing
The EmailParser is tested automatically using GitHub Actions in PHP 7.0 to PHP 8.5.
For the tests execution, the package atk14/tester is used. It is just a wrapping script for phpunit/phpunit.
Install required dependencies:
composer update
Run tests:
cd test
../vendor/bin/run_unit_tests
License
EmailParser is free software distributed under the terms of the MIT license
yarri/email-parser 适用场景与选型建议
yarri/email-parser 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 17 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 05 月 25 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 yarri/email-parser 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 yarri/email-parser 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 17
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 19
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-05-25