mailcapture/mailcapture-php
Composer 安装命令:
composer require --dev mailcapture/mailcapture-php
包简介
Official PHP SDK for the MailCapture email testing API
README 文档
README
Official PHP SDK for MailCapture — a real email capture API for integration testing OTP codes, verification links, and other transactional emails.
Requirements
- PHP 8.1+
- Guzzle 7 (
guzzlehttp/guzzle)
Installation
composer require mailcapture/mailcapture-php
Quick start
use MailCapture\MailCapture; $mc = new MailCapture($_ENV['MAILCAPTURE_API_KEY']); $mc->ping(); // validates key, caches username // In your test: $mc->delete('signup'); $yourApp->register($mc->address('signup')); // e.g. "alice-signup@mailcapture.app" $email = $mc->waitFor('signup', timeout: 15.0); echo $email->subject; // "Verify your account" echo $email->otp; // "123456" — extracted automatically
The pattern for integration tests
use MailCapture\MailCapture; use MailCapture\Model\Capture; use PHPUnit\Framework\TestCase; class UserRegistrationTest extends TestCase { private static MailCapture $mc; public static function setUpBeforeClass(): void { self::$mc = new MailCapture($_ENV['MAILCAPTURE_API_KEY']); self::$mc->ping(); } protected function setUp(): void { self::$mc->delete('signup'); // clean inbox before every test } public function testUserReceivesVerificationEmail(): void { $inbox = self::$mc->inbox('signup'); $this->app->register($inbox->getAddress()); // "alice-signup@mailcapture.app" $email = $inbox->waitFor(timeout: 10.0); $this->assertSame('Verify your account', $email->subject); $this->assertMatchesRegularExpression('/^\d{6}$/', $email->otp); $this->assertLessThan(5000, $email->latencyMs); } }
API reference
new MailCapture($apiKey, ...)
$mc = new MailCapture( apiKey: $_ENV['MAILCAPTURE_API_KEY'], baseUrl: 'http://localhost:3002', // override for local dev (default: https://mailcapture.app) requestTimeout: 15.0, // seconds, default 10.0 username: 'alice', // pre-set to skip ping() (optional) );
ping() → PingResult
Validates your API key and returns your address template. Caches your username so address() works without a network call.
$result = $mc->ping(); echo $result->username; // "alice" echo $result->addressTemplate; // "alice-{tag}@mailcapture.app" echo $result->example; // "alice-signup@mailcapture.app"
waitFor(tag, timeout, pollTimeout, after) → Capture
Long-polls the API and returns the first email captured for the given tag. The server holds the connection open — no busy-waiting.
// Named arguments (recommended) $email = $mc->waitFor('signup', timeout: 15.0); // Full options $email = $mc->waitFor( tag: 'signup', timeout: 15.0, // total seconds to wait (default 30) pollTimeout: 5, // per-poll server timeout in seconds, max 30 (default 10) after: new DateTime('-30 seconds'), // only captures after this time );
Throws MailCaptureTimeoutException if no email arrives in time.
inbox(tag) → Inbox
Returns a scoped Inbox for a tag. Keeps test code clean.
$inbox = $mc->inbox('password-reset'); $inbox->getAddress() // "alice-password-reset@mailcapture.app" $inbox->waitFor(timeout: 10.0) // Capture $inbox->list(limit: 5) // CaptureList $inbox->clear() // deletes all captures for this tag
address(tag) → string
Generates the capture email address synchronously. Requires ping() first (or username in the constructor).
$mc->ping(); echo $mc->address('signup'); // "alice-signup@mailcapture.app"
list(tag, limit, after) → CaptureList
Lists recent captures (newest first).
$result = $mc->list(tag: 'signup', limit: 10); foreach ($result->items as $email) { echo $email->subject . PHP_EOL; }
get(captureId) → Capture
Get a single capture by ID. Throws MailCaptureNotFoundException if not found.
delete(tag) → void
Deletes all captures for a tag. Use in setUp() for test isolation.
The Capture object
$email->id // string — UUID $email->tag // string — e.g. "signup" $email->subject // string — email subject line $email->otp // ?string — extracted code, null if none detected $email->bodyText // ?string — plain-text body $email->bodyHtml // ?string — HTML body $email->latencyMs // int — send-to-capture time in ms $email->status // string — e.g. "captured" $email->receivedAt // string — ISO 8601 timestamp
The otp field is extracted automatically. If your OTP is embedded in a sentence, the service finds it for you.
Exception handling
All exceptions extend MailCaptureException extends \RuntimeException and have getErrorCode().
use MailCapture\Exception\{ MailCaptureAuthException, MailCaptureTimeoutException, MailCaptureNotFoundException, MailCaptureNetworkException, }; try { $email = $mc->waitFor('signup', timeout: 10.0); } catch (MailCaptureTimeoutException $e) { echo "Waited {$e->getWaitedSeconds()}s for tag: {$e->getTag()}" . PHP_EOL; echo "Did the email send? Check your email service logs." . PHP_EOL; } catch (MailCaptureAuthException $e) { echo "Check your MAILCAPTURE_API_KEY environment variable." . PHP_EOL; } catch (MailCaptureNetworkException $e) { echo "Network error: " . $e->getPrevious()?->getMessage() . PHP_EOL; }
| Exception | getErrorCode() |
When |
|---|---|---|
MailCaptureAuthException |
UNAUTHORIZED |
Invalid or revoked API key |
MailCaptureTimeoutException |
TIMEOUT |
waitFor exceeded timeout |
MailCaptureNotFoundException |
NOT_FOUND |
get() — capture not found |
MailCaptureNetworkException |
NETWORK_ERROR |
Could not reach the API |
MailCaptureApiException |
varies | Unexpected API error |
Testing with a mock HTTP client
Inject a Guzzle mock client to test your code without hitting the real API:
use GuzzleHttp\Client; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; use MailCapture\MailCapture; $mock = new MockHandler([ new Response(200, ['Content-Type' => 'application/json'], json_encode([ 'items' => [[ 'id' => 'test-id', 'tag' => 'signup', 'subject' => 'Welcome', 'otp' => '123456', 'body_text' => null, 'body_html' => null, 'latency_ms' => 50, 'status' => 'captured', 'received_at' => '2024-01-01T00:00:00+00:00', ]], 'count' => 1, 'next_after' => '2024-01-01T00:00:01+00:00', ])), ]); $stack = HandlerStack::create($mock); $mc = new MailCapture('mc_testkey', httpClient: new Client(['handler' => $stack])); $email = $mc->waitFor('signup', timeout: 5.0); assert($email->otp === '123456');
Laravel / Symfony integration
// Laravel: AppServiceProvider $this->app->singleton(MailCapture::class, fn() => new MailCapture(config('services.mailcapture.key')) ); // Symfony: services.yaml services: MailCapture\MailCapture: arguments: $apiKey: '%env(MAILCAPTURE_API_KEY)%'
Local development
$mc = new MailCapture($_ENV['MAILCAPTURE_API_KEY'], baseUrl: 'http://localhost:3002');
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-22