smartilabs / php-imap
PHP IMAP 客户端
Requires
- php: >=5.5.9
- ext-fileinfo: *
- ext-iconv: *
- ext-json: *
- ext-mbstring: *
- ext-openssl: *
- illuminate/pagination: >=5.0.0
- nesbot/carbon: >=1.0
- symfony/http-foundation: >=2.8.0
README
描述
PHP-IMAP 是一个用于常见 IMAP 通信的包装器,无需安装/启用 php-imap 模块。协议完全集成,因此支持 IMAP IDLE 操作和“新”OAuth 认证过程。您可以启用 php-imap
模块来处理边缘情况,提高消息解码质量,如果您想使用如 pop3 这样的旧协议,则必须使用它。
Wiki: webklex/php-imap/wiki
Laravel 包装器: webklex/laravel-imap
目录
安装
1.) 安装解码模块
sudo apt-get install php*-mbstring php*-mcrypt && sudo apache2ctl graceful
1.1.) (可选) 如果您遇到编码问题,请安装 php-imap 模块
sudo apt-get install php*-imap && sudo apache2ctl graceful
您还可能想检查 phpinfo()
看看扩展是否启用。
2.) 现在运行以下命令来安装 PHP-IMAP 软件包
composer require webklex/php-imap
3.) 创建您自己的自定义配置文件,例如 config/imap.php
配置
支持的协议
imap
— 使用 IMAP [默认]legacy-imap
— 使用 php imap 模块pop3
— 使用 POP3nntp
— 使用 NNTP
以下加密方法得到支持
false
— 禁用加密ssl
— 使用 SSLtls
— 使用 TLSstarttls
— 使用 STARTTLS (TLS 的别称) (仅限旧版)notls
— 使用 NoTLS (仅限旧版)
详细的 config/imap.php 配置
default
— 使用默认账户。如果默认账户缺少参数,则将使用软件包默认值。如果默认账户缺少参数,请将此功能禁用。accounts
— 所有可用账户default
— 账户标识符(在这种情况下为default
,但也可以为fooBar
等)。host
— imap 主机port
— imap 端口encryption
— 希望的加密方法validate_cert
— 决定您是否想要验证证书username
— imap 账户用户名password
— imap 账户密码authentication
— imap 认证方法。使用oauth
来使用 Google 等的 OAuth。
date_format
— 默认日期格式用于将给定的 Carbon::class 对象转换为有效的日期字符串。(d-M-Y
、d-M-y
、d M y
)options
— 额外的获取选项delimiter
— 可以使用任何支持的字符,例如 "。" 或 "/" 等。fetch
—IMAP::FT_UID
(通过获取消息正文标记为已读)或IMAP::FT_PEEK
(获取消息不设置“已读”标志)。fetch_body
— 如果设置为false
,则所有消息将获取不带正文和任何潜在附件。fetch_flags
— 如果设置为false
,则所有消息将获取不带任何标志。message_key
— 消息键标识选项。fetch_order
— 消息获取顺序。common_folders
— 如果未提供,则假定默认文件夹位置和路径。open
— 对imap_open()
的特殊配置。DISABLE_AUTHENTICATOR
— 禁用身份验证属性。
decoder
— 目前只能设置消息和附件解码器。events
— 默认事件处理配置。masks
— 默认遮罩配置。message
— 默认消息遮罩。attachment
— 默认附件遮罩。
用法
基本用法示例
这是一个基本示例,它将回显所有imap文件夹中的邮件,并将每条消息移入INBOX.read。请注意,这不应该在实际生活中进行测试,只是为了让您了解事物是如何工作的。
use Webklex\PHPIMAP\ClientManager; use Webklex\PHPIMAP\Client; $cm = new ClientManager('path/to/config/imap.php'); // or use an array of options instead $cm = new ClientManager($options = []); /** @var \Webklex\PHPIMAP\Client $client */ $client = $cm->account('account_identifier'); // or create a new instance manually $client = $cm->make([ 'host' => 'somehost.com', 'port' => 993, 'encryption' => 'ssl', 'validate_cert' => true, 'username' => 'username', 'password' => 'password', 'protocol' => 'imap' ]); //Connect to the IMAP Server $client->connect(); //Get all Mailboxes /** @var \Webklex\PHPIMAP\Support\FolderCollection $folders */ $folders = $client->getFolders(); //Loop through every Mailbox /** @var \Webklex\PHPIMAP\Folder $folder */ foreach($folders as $folder){ //Get all Messages of the current Mailbox $folder /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->messages()->all()->get(); /** @var \Webklex\PHPIMAP\Message $message */ foreach($messages as $message){ echo $message->getSubject().'<br />'; echo 'Attachments: '.$message->getAttachments()->count().'<br />'; echo $message->getHTMLBody(); //Move the current Message to 'INBOX.read' if($message->move('INBOX.read') == true){ echo 'Message has ben moved'; }else{ echo 'Message could not be moved'; } } }
文件夹 / 邮箱
列出所有可用文件夹。
/** @var \Webklex\PHPIMAP\Client $client */ /** @var \Webklex\PHPIMAP\Support\FolderCollection $folders */ $folders = $client->getFolders();
获取特定文件夹。
/** @var \Webklex\PHPIMAP\Client $client */ /** @var \Webklex\PHPIMAP\Folder $folder */ $folder = $client->getFolder('INBOX.name');
oAuth
请参阅维基文章以获取gmail / google mail的设置。
基本oAuth示例。
use Webklex\PHPIMAP\Clientmanager; $cm = new Clientmanager(); /** @var \Webklex\PHPIMAP\Client $client */ $client = $cm->make([ 'host' => 'imap.gmail.com', 'port' => 993, 'encryption' => 'ssl', 'validate_cert' => true, 'username' => 'example@gmail.com', 'password' => 'ACCESS-TOKEN', 'authentication' => "oauth", 'protocol' => 'imap' ]); //Connect to the IMAP Server $client->connect();
IDLE
每次收到新消息时,服务器将通知客户端并返回新消息。
/** @var \Webklex\PHPIMAP\Folder $folder */ $folder->idle(function($message){ echo $message->subject."\n"; });
搜索邮件。
搜索特定电子邮件。
/** @var \Webklex\PHPIMAP\Folder $folder */ //Get all messages /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->all()->get(); //Get all messages from example@domain.com /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->from('example@domain.com')->get(); //Get all messages since march 15 2018 /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->since('15.03.2018')->get(); //Get all messages within the last 5 days $messages = $folder->query()->since(\Carbon\Carbon::now()->subDays(5))->get(); //Get all messages containing "hello world" /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->text('hello world')->get(); //Get all unseen messages containing "hello world" /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->unseen()->text('hello world')->get(); //Extended custom search query for all messages containing "hello world" //and have been received since march 15 2018 /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->text('hello world')->since('15.03.2018')->get(); $messages = $folder->query()->Text('hello world')->Since('15.03.2018')->get(); $messages = $folder->query()->whereText('hello world')->whereSince('15.03.2018')->get(); // Build a custom search query /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query() ->where([['TEXT', 'Hello world'], ['SINCE', \Carbon\Carbon::parse('15.03.2018')]]) ->get(); //!EXPERIMENTAL! //Get all messages NOT containing "hello world" /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->notText('hello world')->get(); $messages = $folder->query()->not_text('hello world')->get(); $messages = $folder->query()->not()->text('hello world')->get(); //Get all messages by custom search criteria /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->where(["CUSTOM_FOOBAR" => "fooBar"]])->get();
用于更好地阅读代码的可用搜索别名。
// Folder::search() is just an alias for Folder::query() /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->search()->text('hello world')->since('15.03.2018')->get(); // Folder::messages() is just an alias for Folder::query() /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->messages()->text('hello world')->since('15.03.2018')->get();
所有可用的查询/搜索方法可以在以下位置找到: Query::class
可用的搜索标准。
ALL
— 返回所有符合其他标准条件的消息。ANSWERED
— 匹配设置了 \ANSWERED 标志的消息。BCC
"字符串" — 匹配Bcc:字段中包含"字符串"的消息。BEFORE
"日期" — 匹配Date:日期在"日期"之前的消息。BODY
"字符串" — 匹配正文包含"字符串"的消息。CC
"字符串" — 匹配Cc:字段中包含"字符串"的消息。DELETED
— 匹配已删除的消息。FLAGGED
— 匹配设置了 \FLAGGED(有时称为Important或Urgent)标志的消息。FROM
"字符串" — 匹配From:字段中包含"字符串"的消息。KEYWORD
"字符串" — 匹配包含"字符串"作为关键字的消息。NEW
— 匹配新消息。NOT
— 不匹配。OLD
— 匹配旧消息。ON
"日期" — 匹配Date:日期匹配"日期"的消息。RECENT
— 匹配设置了 \RECENT 标志的消息。SEEN
— 匹配已读的消息(已设置 \SEEN 标志)。SINCE
"日期" — 匹配Date:日期在"日期"之后的消息。SUBJECT
"字符串" — 匹配Subject中包含"字符串"的消息。TEXT
"字符串" — 匹配包含文本"字符串"的消息。TO
"字符串" — 匹配To中包含"字符串"的消息。UNANSWERED
— 匹配未回答的消息。UNDELETED
— 匹配未删除的消息。UNFLAGGED
— 匹配未标记的消息。UNKEYWORD
"字符串" — 匹配不包含关键字"字符串"的消息。UNSEEN
— 匹配尚未阅读的消息
更多信息
- https://php.ac.cn/manual/en/function.imap-search.php
- https://tools.ietf.org/html/rfc1176
- https://tools.ietf.org/html/rfc1064
- https://tools.ietf.org/html/rfc822
- https://gist.github.com/martinrusev/6121028
结果限制
限制请求邮件
/** @var \Webklex\PHPIMAP\Folder $folder */ //Get all messages for page 2 since march 15 2018 where each page contains 10 messages /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->since('15.03.2018')->limit(10, 2)->get();
计数消息
计算所有符合当前搜索条件的可用消息数量
/** @var \Webklex\PHPIMAP\Folder $folder */ //Count all messages /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $count = $folder->query()->all()->count(); //Count all messages since march 15 2018 $count = $folder->query()->since('15.03.2018')->count();
分页
分页查询
/** @var \Webklex\PHPIMAP\Folder $folder */ /** @var \Illuminate\Pagination\LengthAwarePaginator $paginator */ $paginator = $folder->query()->since('15.03.2018')->paginate();
分页消息集合
/** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ /** @var \Illuminate\Pagination\LengthAwarePaginator $paginator */ $paginator = $messages->paginate();
查看分页列表的示例
/** @var \Webklex\PHPIMAP\Folder $folder */ /** @var \Illuminate\Pagination\LengthAwarePaginator $paginator */ $paginator = $folder->search() ->since(\Carbon\Carbon::now()->subDays(14))->get() ->paginate($perPage = 5, $page = null, $pageName = 'imap_blade_example');
<table> <thead> <tr> <th>UID</th> <th>Subject</th> <th>From</th> <th>Attachments</th> </tr> </thead> <tbody> <?php if($paginator->count() > 0): ?> <?php foreach($paginator as $message): ?> <tr> <td><?php echo $message->getUid(); ?></td> <td><?php echo $message->getSubject(); ?></td> <td><?php echo $message->getFrom()[0]->mail; ?></td> <td><?php echo $message->getAttachments()->count() > 0 ? 'yes' : 'no'; ?></td> </tr> <?php endforeach; ?> <?php else: ?> <tr> <td colspan="4">No messages found</td> </tr> <?php endif; ?> </tbody> </table> <?php echo $paginator->links(); ?>
您还可以对文件夹、附件或FlagCollection实例进行分页。
查看示例
您可以在 /examples 下找到一些blade示例。
获取特定消息
通过uid获取特定消息(请注意,uid不是唯一的,可能会更改)
/** @var \Webklex\PHPIMAP\Folder $folder */ /** @var \Webklex\PHPIMAP\Message $message */ $message = $folder->query()->getMessage($msgn = 1);
消息标志
标记或“取消标记”消息
/** @var \Webklex\PHPIMAP\Message $message */ $message->setFlag(['Seen', 'Spam']); $message->unsetFlag('Spam');
在获取时将所有消息标记为“已读”
/** @var \Webklex\PHPIMAP\Folder $oFolder */ /** @var \Webklex\PHPIMAP\Support\MessageCollection $aMessage */ $aMessage = $oFolder->query()->text('Hello world')->markAsRead()->get();
在获取时不要将所有消息标记为“已读”
/** @var \Webklex\PHPIMAP\Folder $oFolder */ /** @var \Webklex\PHPIMAP\Support\MessageCollection $aMessage */ $aMessage = $oFolder->query()->text('Hello world')->leaveUnread()->get();
附件
保存消息附件
/** @var \Webklex\PHPIMAP\Message $message */ /** @var \Webklex\PHPIMAP\Support\AttachmentCollection $attachments */ $attachments = $message->getAttachments(); $attachments->each(function ($attachment) { /** @var \Webklex\PHPIMAP\Attachment $attachment */ $attachment->save("/some/path/"); });
高级获取
获取不带正文获取的消息(减少负载)
/** @var \Webklex\PHPIMAP\Folder $folder */ /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereText('Hello world')->setFetchBody(false)->get(); /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereAll()->setFetchBody(false)->get();
获取不带正文、标记和附件获取的消息(减少负载)
/** @var \Webklex\PHPIMAP\Folder $folder */ /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereText('Hello world') ->setFetchFlags(false) ->setFetchBody(false) ->get(); /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereAll() ->setFetchFlags(false) ->setFetchBody(false) ->get();
更改消息获取顺序
/** @var \Webklex\PHPIMAP\Folder $folder */ /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereText('Hello world') ->setFetchOrder('asc') ->get(); /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereAll() ->setFetchOrderAsc() ->get(); /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereAll() ->fetchOrderAsc() ->get(); /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereText('Hello world') ->setFetchOrder('desc') ->get(); /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereAll() ->setFetchOrderDesc() ->get(); /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */ $messages = $folder->query()->whereAll() ->fetchOrderDesc() ->get();
事件
以下事件可用
Webklex\PHPIMAP\Events\MessageNewEvent($message)
— 可由Folder::idle
触发Webklex\PHPIMAP\Events\MessageDeletedEvent($message)
— 由Message::delete
触发Webklex\PHPIMAP\Events\MessageRestoredEvent($message)
— 由Message::restore
触发Webklex\PHPIMAP\Events\MessageMovedEvent($old_message, $new_message)
— 由Message::move
触发Webklex\PHPIMAP\Events\MessageCopiedEvent($old_message, $new_message)
— 由Message::copy
触发Webklex\PHPIMAP\Events\FlagNewEvent($flag)
— 由Message::setFlag
触发Webklex\PHPIMAP\Events\FlagDeletedEvent($flag)
— 由Message::unsetFlag
触发Webklex\PHPIMAP\Events\FolderNewEvent($folder)
— 可由Client::createFolder
触发Webklex\PHPIMAP\Events\FolderDeletedEvent($folder)
— 由Folder::delete
触发Webklex\PHPIMAP\Events\FolderMovedEvent($old_folder, $new_folder)
— 由Folder::move
触发
创建并注册您自己的自定义事件
class CustomMessageNewEvent extends Webklex\PHPIMAP\Events\MessageNewEvent { /** * Create a new event instance. * @var \Webklex\PHPIMAP\Message[] $messages * @return void */ public function __construct($messages) { $this->message = $messages[0]; echo "New message: ".$this->message->subject."\n"; } } /** @var \Webklex\PHPIMAP\Client $client */ $client->setEvent("message", "new", CustomMessageNewEvent::class);
或将其设置在您的配置文件中的 events.message.new
下。
掩码
PHP-IMAP 已经带有两个默认掩码 MessageMask::class 和 AttachmentMask::class。
掩码实例必须手动调用,并设计用于添加自定义功能。
您可以通过调用无参数的掩码方法来调用默认掩码。
/** @var \Webklex\PHPIMAP\Message $message */ $mask = $message->mask();
有几种方法可以设置默认掩码
/** @var \Webklex\PHPIMAP\Client $client */ /** @var \Webklex\PHPIMAP\Message $message */ $message_mask = \Webklex\PHPIMAP\Support\Masks\MessageMask::class; $client->setDefaultMessageMask($message_mask); $message->setMask($message_mask); $mask = $message->mask($message_mask);
最后一个不会设置掩码,而是使用提供的掩码生成一个掩码实例。
您还可以在 config/imap.php
文件中的 masks
下设置默认掩码。
您还可以在 附件 上应用掩码
/** @var \Webklex\PHPIMAP\Client $client */ /** @var \Webklex\PHPIMAP\Attachment $attachment */ $attachment_mask = \Webklex\PHPIMAP\Support\Masks\AttachmentMask::class; $client->setDefaultAttachmentMask($attachment_mask); $attachment->setMask($attachment_mask); $mask = $attachment->mask($attachment_mask);
如果您想实现自己的掩码,请扩展 MessageMask::class、AttachmentMask::class 或 Mask::class 并实现您想要的逻辑
/** @var \Webklex\PHPIMAP\Message $message */ class CustomMessageMask extends \Webklex\PHPIMAP\Support\Masks\MessageMask { /** * New custom method which can be called through a mask * @return string */ public function token(){ return implode('-', [$this->message_id, $this->uid, $this->message_no]); } } $mask = $message->mask(CustomMessageMask::class); echo $mask->token().'@'.$mask->uid;
更多示例可以在这里找到
特殊
找到包含消息的文件夹
/** @var \Webklex\PHPIMAP\Message $message */ $folder = $message->getFolder();
支持
如果您遇到任何问题或发现错误,请不要犹豫,创建一个新的 问题。然而,请注意,可能需要一些时间才能得到回答。不相关、粗鲁或侮辱性的问题将被无通知删除。
如果您需要即时或商业支持,请随时给我发送邮件至 github@webklex.com。
注意事项
如果您在问题中编写源代码,请考虑正确格式化。这会让阅读变得更轻松,人们也更可能进行评论并提供帮助 :)
``` php
echo '您的PHP代码...';
```
将变为
echo 'your php code...';
功能与pull请求
每个人都可以为这个项目做出贡献。每个pull请求都会被考虑,但也有可能被拒绝。为了避免不必要的劳动,如果您计划进行较大的更改,请首先考虑创建一个功能问题。当然,如果您只是希望增加一个功能,也可以创建一个新的功能问题 ;)
文档
Client::class
Message::class
Folder::class
Query::class
Attachment::class
Mask::class
MessageMask::class
AttachmentMask::class
MessageCollection::class
扩展 Illuminate\Support\Collection::class
FlagCollection::class
扩展 Illuminate\Support\Collection::class
AttachmentCollection::class
扩展 Illuminate\Support\Collection::class
FolderCollection::class
扩展 Illuminate\Support\Collection::class
已知问题
变更日志
请参阅CHANGELOG以获取有关最近更改的更多信息。
安全
如果您发现任何安全相关的问题,请发送电子邮件至github@webklex.com而不是使用问题跟踪器。
致谢
许可证
MIT许可(MIT)。请参阅许可文件以获取更多信息。