saintsloth/ddeboer-imap

面向对象的 PHP IMAP 库

维护者

详细信息

github.com/saintsloth/imap

源代码

1.0.0 2022-10-27 16:26 UTC

This package is auto-updated.

Last update: 2024-09-29 05:57:13 UTC


README

一个用于通过 IMAP 读取和处理电子邮件的 PHP 7.1+ 库。

此库需要已安装 IMAPiconvMultibyte String 扩展。

目录

  1. 功能请求
  2. 安装
  3. 使用
    1. 连接和验证
    2. 邮箱
    3. 邮件
      1. 搜索邮件
      2. 未知搜索条件:OR
      3. 邮件属性和操作
    4. 邮件附件
    5. 嵌入邮件
    6. 超时
  4. 模拟库
  5. 运行测试
    1. 使用 Docker 运行测试

功能请求

Feature Requests

安装

安装 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);

您可以为邮箱中的任何邮件(通过 UIDs)批量设置或清除任何 标志

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

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

警告 如果您批量修改标志,则必须检索新的 Message 实例以刷新单个邮件的标志。

邮件

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

$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。如果您想使用这些不受支持的搜索条件,则需要手动修补最新版本(此提交时的 imap-2007f,2011 年 7 月 23 日)并重新编译 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

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

$message->markAsSeen();

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

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

将消息移动到另一个邮箱

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

删除消息

$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
    }
}

嵌入式消息具有与普通消息相同的API,除了标志和复制、移动或删除等操作。

超时

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

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

由于IMAP服务器世界的异构性和实现这种小小收益所承担的高复杂度负担,我们选择了后者。

模拟库

接口的存在提供了可模拟性。查看MockabilityTest以获取模拟工作流程的示例。

运行测试

该库在Travis CI上对本地Dovecot服务器进行了功能测试。

如果您有自己的IMAP(测试)账户,您可以通过提供您的IMAP凭据在本地运行测试

$ composer install
$ IMAP_SERVER_NAME="my.imap.server.com" IMAP_SERVER_PORT="60993" IMAP_USERNAME="johndoe" IMAP_PASSWORD="p4ssword" vendor/bin/phpunit

您还可以将phpunit.xml.dist文件复制到自定义的phpunit.xml,并将这些环境变量放入其中

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
    bootstrap="./vendor/autoload.php"
    colors="true"
    verbose="true"
>
    <testsuites>
        <testsuite name="ddeboer/imap">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist>
            <directory suffix=".php">./src</directory>
        </whitelist>
    </filter>
    <php>
        <env name="IMAP_SERVER_NAME" value="my.imap.server.com" />
        <env name="IMAP_SERVER_PORT" value="60993" />
        <env name="IMAP_USERNAME" value="johndoe" />
        <env name="IMAP_PASSWORD" value="p4ssword" />
    </php>
</phpunit>

警告 测试会创建新的邮箱而不会删除它们。

使用 Docker 运行测试

如果您已安装Docker,可以使用以下命令在本地运行测试

$ docker-compose run tests