ddeboer/imap

面向对象的PHP IMAP

维护者

详细信息

github.com/ddeboer/imap

源代码

问题

资助包维护!
ddeboer
Slamdunk

安装次数: 2,966,205

依赖项: 15

建议者: 0

安全: 0

星标: 884

关注者: 33

分支: 253

开放问题: 66

1.19.0 2023-11-20 14:41 UTC

README

Latest Stable Version Downloads Integrate Code Coverage

一个用于通过IMAP协议读取和处理电子邮件的PHP IMAP库,采用健壮的面向对象架构。

此库需要PHP >= 8.2,并安装IMAPiconvMultibyte String 扩展。

安装

安装IMAP库的推荐方法是使用 Composer

$ composer require ddeboer/imap

此命令需要您全局安装Composer,如Composer文档的安装章节中所述。

用法

连接和认证

use Ddeboer\Imap\Server;

$server = new Server('imap.gmail.com');

// $connection is instance of \Ddeboer\Imap\Connection
$connection = $server->authenticate('my_username', 'my_password');

您可以指定服务器端口、标志和参数

$server = new Server(
    $hostname, // required
    $port,     // defaults to '993'
    $flags,    // defaults to '/imap/ssl/validate-cert'
    $parameters
);

邮箱

从邮件服务器检索邮箱(也称为邮件文件夹)并遍历它们

$mailboxes = $connection->getMailboxes();

foreach ($mailboxes as $mailbox) {
    // Skip container-only mailboxes
    // @see https://secure.php.net/manual/en/function.imap-getmailboxes.php
    if ($mailbox->getAttributes() & \LATT_NOSELECT) {
        continue;
    }

    // $mailbox is instance of \Ddeboer\Imap\Mailbox
    printf('Mailbox "%s" has %s messages', $mailbox->getName(), $mailbox->count());
}

或检索特定邮箱

$mailbox = $connection->getMailbox('INBOX');

删除邮箱

$connection->deleteMailbox($mailbox);

您可以批量设置或清除邮箱消息的任何标志(通过UID)

$mailbox->setFlag('\\Seen \\Flagged', ['1:5', '7', '9']);
$mailbox->setFlag('\\Seen', '1,3,5,6:8');

$mailbox->clearFlag('\\Flagged', '1,3');

警告 在批量修改标志的情况下,您必须检索新的消息实例以刷新单个消息的标志。

消息

从邮箱检索消息(电子邮件)并遍历它们

$messages = $mailbox->getMessages();

foreach ($messages as $message) {
    // $message is instance of \Ddeboer\Imap\Message
}

将新消息(刚刚发送的)插入“已发送”邮箱,并将其标记为已读

$mailbox = $connection->getMailbox('Sent');
$mailbox->addMessage($messageMIME, '\\Seen');

注意,消息应该是MIME格式(如RFC2045中所述)的字符串。

搜索消息

use Ddeboer\Imap\SearchExpression;
use Ddeboer\Imap\Search\Email\To;
use Ddeboer\Imap\Search\Text\Body;

$search = new SearchExpression();
$search->addCondition(new To('me@here.com'));
$search->addCondition(new Body('contents'));

$messages = $mailbox->getMessages($search);

警告 目前我们无法同时转义空格和双引号。目前只能正确转义空格。您可以使用 Ddeboer\Imap\Search\RawExpression 来自行编写完整的搜索条件。

消息还可以按照 imap_sort 函数排序

$today = new DateTimeImmutable();
$thirtyDaysAgo = $today->sub(new DateInterval('P30D'));

$messages = $mailbox->getMessages(
    new Ddeboer\Imap\Search\Date\Since($thirtyDaysAgo),
    \SORTDATE, // Sort criteria
    true // Descending order
);

未知搜索标准:OR

请注意,PHP imap库依赖于可从 https://www.washington.edu/imap/ 获取的 c-client 库,该库不完全支持某些IMAP4搜索标准,如OR。如果您需要这些不受支持的准则,您需要手动修补最新版本(当时为2011年7月23日的imap-2007f)并重新编译PHP以使用修补的c-client库。

顺便说一句,大多数常用搜索标准都可用且功能正常,请在./src/Search中查看。

参考

  1. https://stackoverflow.com/questions/36356715/imap-search-unknown-search-criterion-or
  2. imap-2007f.tar.gz: ./src/c-client/mail.c./docs/internal.txt

消息属性和操作

获取消息编号和唯一的 消息ID,格式为 <...>

$message->getNumber();
$message->getId();

获取其他消息属性

$message->getSubject();
$message->getFrom();    // Message\EmailAddress
$message->getTo();      // array of Message\EmailAddress
$message->getDate();    // DateTimeImmutable
$message->isAnswered();
$message->isDeleted();
$message->isDraft();
$message->isSeen();

获取消息头作为 \Ddeboer\Imap\Message\Headers 对象

$message->getHeaders();

获取消息体作为HTML或纯文本(仅第一部分)

$message->getBodyHtml();    // Content of text/html part, if present
$message->getBodyText();    // Content of text/plain part, if present

获取完整消息体(所有部分)

$body = $message->getCompleteBodyHtml();    // Content of text/html part, if present
if ($body === null) { // If body is null, there are no HTML parts, so let's try getting the text body
    $body = $message->getCompleteBodyText();    // Content of text/plain part, if present
}

读取消息体会保留消息为未读状态。如果您想将消息标记为已读

$message->markAsSeen();

或者您也可以设置或清除任何 标志

$message->setFlag('\\Seen \\Flagged');
$message->clearFlag('\\Flagged');

将消息移动到另一个邮箱

$mailbox = $connection->getMailbox('another-mailbox');
$message->move($mailbox);

删除消息

$mailbox->getMessage(1)->delete();
$mailbox->getMessage(2)->delete();
$connection->expunge();

消息附件

获取消息附件(包括内联和附加)并遍历它们

$attachments = $message->getAttachments();

foreach ($attachments as $attachment) {
    // $attachment is instance of \Ddeboer\Imap\Message\Attachment
}

将消息附件下载到本地文件

// getDecodedContent() decodes the attachment’s contents automatically:
file_put_contents(
    '/my/local/dir/' . $attachment->getFilename(),
    $attachment->getDecodedContent()
);

嵌入消息

检查附件是否为嵌入消息并获取它

$attachments = $message->getAttachments();

foreach ($attachments as $attachment) {
    if ($attachment->isEmbeddedMessage()) {
        $embeddedMessage = $attachment->getEmbeddedMessage();
        // $embeddedMessage is instance of \Ddeboer\Imap\Message\EmbeddedMessage
    }
}

EmbedMessage 与普通 Message 具有相同的 API,除了标志和复制、移动或删除等操作。

超时

IMAP 扩展提供了 imap_timeout 函数来调整各种操作的超时秒数。

然而,扩展的实现并没有将功能与特定的上下文或连接相关联,而是全局的。因此,为了不影响库外的功能,我们必须选择是否在每个可选的用户提供的超时周围包装每个 imap_* 调用,或者将这项任务留给用户。

由于 IMAP 服务器世界的异构性和为了如此小的收益而带来的高复杂度负担,我们选择了后者。

模拟库

通过每个 API 存在的接口允许模拟。查看 MockabilityTest 以获取模拟工作流程的示例。

贡献:在本地运行构建

运行构建需要在您的计算机上安装 Docker。

您需要运行的第一个命令是 make start-imap-server,该命令在本地启动 IMAP 服务器。

然后可以通过简单的 make 触发本地构建。

当您完成开发后,使用 make stop-imap-server 停止本地 IMAP 服务器。