beecubu/php-foundation-emailer
Composer 安装命令:
composer require beecubu/php-foundation-emailer
包简介
PHP Object Foundation Framework Emailer library for SMTP, EWS and Microsoft Graph
README 文档
README
PHP Object Foundation Emailer with SMTP, Microsoft Exchange Web Services (EWS) and Microsoft Graph API support. It includes:
- A unified
Emailsender for SMTP, EWS or Microsoft Graph. - A database-agnostic email queue system.
- Helpers for attachments and queued processing.
This package is database-agnostic: it defines the queue interface but does not include any persistence implementation. Use a persistence plugin to provide a concrete queue backend:
beecubu/php-foundation-emailer-mongodb— MongoDB backend.beecubu/php-foundation-emailer-sqlite— SQLite backend.
Requirements
- PHP 7.1+
ext-json,ext-curlbeecubu/php-foundation-coresymfony/mailer5.4php-ews/php-ews(via the configured VCS repo)
Installation
composer require beecubu/php-foundation-emailer
# Plus a persistence plugin (choose one):
composer require beecubu/php-foundation-emailer-mongodb
# or
composer require beecubu/php-foundation-emailer-sqlite
Basic SMTP Example
<?php
use Beecubu\Foundation\Emailer\Entities\Email\Email;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigService;
$config = new EmailConfig();
$config->service = EmailConfigService::SMTP;
$config->from = 'no-reply@example.com';
$config->fromName = 'Example App';
$config->server = 'smtp.example.com';
$config->port = 587;
$config->userName = 'smtp-user';
$config->password = 'smtp-pass';
$config->verifyPeer = true;
$mailer = Email::emailWithEmailConfig($config);
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Welcome',
'<p>Hello!</p>',
false
);
EWS Example
<?php
use Beecubu\Foundation\Emailer\Entities\Email\Email;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigService;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailEWSVersion;
$config = new EmailConfig();
$config->service = EmailConfigService::EWS;
// You can use either the bare host or the full Exchange endpoint URL.
$config->server = 'https://exchange.example.com/EWS/Exchange.asmx';
$config->userName = 'user@example.com';
$config->password = 'password';
$config->version = EmailEWSVersion::VERSION_2010;
$config->verifyPeer = false;
$mailer = Email::emailWithEmailConfig($config);
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'EWS Test',
'<p>Sent via EWS</p>',
false
);
The server field accepts any of these formats — all are normalized internally:
exchange.example.comexchange.example.com/EWS/Exchange.asmxhttps://exchange.example.com/EWS/Exchange.asmx
SMTP Options
SMTP supports explicit overrides, but the recommended configuration is to let Symfony resolve them automatically.
<?php
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigAuth;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigEncryption;
$config->authMode = EmailConfigAuth::AUTO;
$config->encryption = EmailConfigEncryption::Encryption_Auto;
$config->verifyPeer = true;
Available options:
EmailConfigAuth::AUTO: recommended, delegates authentication negotiation to Symfony.EmailConfigAuth::NONE("None"): disables SMTP credentials. When using this mode,userNameandpasswordare not required.EmailConfigAuth::PLAIN,LOGIN,CRAM_MD5: accepted for configuration compatibility, but the framework now prioritizes Symfony's automatic negotiation for forward compatibility.EmailConfigEncryption::Encryption_Auto: recommended, delegates TLS behavior to Symfony.EmailConfigEncryption::Encryption_TLS: forces SMTP with STARTTLS-style negotiation.EmailConfigEncryption::Encryption_SSL: forces implicit SMTPS.EmailConfigEncryption::Encryption_None: disables TLS at transport construction time.
Microsoft Graph Example
Microsoft Graph is the modern Microsoft API for Office 365 / Exchange Online. Authentication uses OAuth 2.0 client credentials (app-only), which means no user interaction is required — the application authenticates directly with Azure AD using a tenantId, clientId and clientSecret.
1) Register an Azure AD application
- Go to Azure Portal → Azure Active Directory → App registrations → New registration.
- Give it a name (e.g.
MyApp Emailer) and register it. - Go to API permissions → Add a permission → Microsoft Graph → Application permissions.
- Add
Mail.Send. - Click Grant admin consent (required for application permissions).
- Go to Certificates & secrets → New client secret. Copy the secret value immediately.
- Note the Application (client) ID and the Directory (tenant) ID from the Overview page.
2) Configure and send
<?php
use Beecubu\Foundation\Emailer\Entities\Email\Email;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigService;
$config = new EmailConfig();
$config->service = EmailConfigService::GRAPH;
$config->from = 'no-reply@yourdomain.com'; // must be a mailbox in your tenant
$config->fromName = 'Example App';
$config->tenantId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
$config->clientId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy';
$config->clientSecret = 'your-client-secret';
$config->verifyPeer = true;
$mailer = Email::emailWithEmailConfig($config);
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Graph Test',
'<p>Sent via Microsoft Graph</p>',
false
);
How it works internally
- On the first send,
Graphrequests an access token fromhttps://login.microsoftonline.com/{tenantId}/oauth2/v2.0/tokenusing the client credentials grant. - The token is cached in memory until 60 seconds before its expiry (typically 1 hour), so subsequent sends within the same process reuse it.
- The email is sent via
POST https://graph.microsoft.com/v1.0/users/{from}/sendMail. - On failure, an
EmailGraphSendingErrorexception is thrown with the error message returned by the API.
Note: The
fromaddress must be a valid mailbox within your Azure AD tenant. The registered application needs theMail.Sendapplication permission (not delegated) for this flow to work without a signed-in user.
Verification Model
EmailConfig now separates two different concerns:
sendingVerified: confirms that the technical delivery configuration has passed a functional send test.ownershipVerified: confirms that the mailbox infromhas been validated by a verification token.
Related internal fields:
sendingVerification: hash used to detect delivery-related configuration changes.ownershipVerification: token tied to thefrommailbox ownership.
Behavior:
- Changing SMTP / EWS / Graph technical settings invalidates
sendingVerified. - Changing
frominvalidatesownershipVerified. verifySending()marks the config as delivery-verified.verifyOwnershipToken($token)validates mailbox ownership.
Attachments
use Beecubu\Foundation\Emailer\Entities\Email\EmailAttachment;
$attachments = [
EmailAttachment::create('report.pdf', $pdfBinary, 'application/pdf'),
];
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Report',
'<p>Attached.</p>',
false,
$attachments
);
Attachments work the same way across all three transports (SMTP, EWS, Graph).
Queueing Emails
When $queue = true, emails are stored in the configured persistence backend and can be sent later.
1) Initialize persistence
Before queuing any emails, register a persistence backend using the plugin's bootstrap:
// MongoDB
use Beecubu\Foundation\Emailer\MongoDB\RepositoryBootstrap;
RepositoryBootstrap::register();
// or SQLite
use Beecubu\Foundation\Emailer\SQLite\RepositoryBootstrap;
RepositoryBootstrap::register();
2) Queue an email
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Queued Email',
'<p>This will be queued.</p>',
true
);
3) Processing the Queue
Extend EmailQueueSender to provide a config for each queued item:
<?php
use Beecubu\Foundation\Emailer\Entities\EmailQueueItem\EmailQueueSender;
use Beecubu\Foundation\Emailer\Entities\EmailQueueItem\EmailQueueItem;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
class MyQueueSender extends EmailQueueSender
{
protected static function getEmailConfigByItem(EmailQueueItem $item): ?EmailConfig
{
// Resolve the EmailConfig for this ownerId.
// Return null if it does not exist.
return MyEmailConfigRepo::findByOwnerId($item->ownerId);
}
}
// Silent (default is verbose)
MyQueueSender::execute();
// With console logs
MyQueueSender::execute(verbose: true);
When $verbose is enabled, each email processed prints:
- Before sending: recipient, subject and owner ID.
- On success: confirmation line.
- On error: the error message.
The queue will:
- Fetch the next email in
waitingstate. - Mark it as
sendingto avoid duplicates across concurrent workers. - Send it via the configured transport (SMTP, EWS or Graph).
- Remove it from the queue on success.
- Mark it as
erroron failure and store: error: a short error message.errorDebug: a technical debug log with transport-specific details when available.
Architecture
php-foundation-emailer (core, DB-agnostic)
↑ implemented by
php-foundation-emailer-mongodb (MongoDB plugin)
php-foundation-emailer-sqlite (SQLite plugin)
The core package defines IEmailQueueRepository and EmailQueueProvider. Plugins provide concrete implementations and register them via RepositoryBootstrap::register().
Notes
- For SMTP, this package uses Symfony Mailer.
- For EWS, it uses
php-ews/php-ews(on-premise Exchange). - For Microsoft Graph, it uses the Graph REST API directly via
ext-curl(no extra SDK required). This is the recommended approach for Office 365 / Exchange Online. - On queued failures, SMTP stores Symfony transport debug output, Graph stores endpoint/HTTP/API diagnostic context, and EWS stores request/response metadata in
errorDebug.
beecubu/php-foundation-emailer 适用场景与选型建议
beecubu/php-foundation-emailer 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 57 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 11 月 16 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 beecubu/php-foundation-emailer 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 beecubu/php-foundation-emailer 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 57
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 14
- 依赖项目数: 2
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-11-16