PHP Library — Composer Package
composer require nsoftware/email-validator-php
Type-safe API client for email-validaton.com. Async, cached, Laravel-ready.
Installation
composer require nsoftware/email-validator-php
Requirements: PHP 8.1+, Guzzle 7, PSR-6 cache (optional), PSR-3 logger (optional).
Quick Start
<?php
require 'vendor/autoload.php';
use NSoftware\EmailValidator\Client;
$client = new Client('ev_your_api_key');
// Verify one email
$result = $client->verify('user@example.com');
if ($result->isValid()) {
echo "Valid — confidence: {$result->confidence}";
}
if ($result->isDisposable()) {
echo "Disposable email — reject!";
}
Async Verification
$client->verifyAsync('user@domain.com')
->then(fn($result) => echo $result->status);
// Bulk async with controlled concurrency
$client->verifyBulkAsync($emails, concurrency: 10)
->then(function(array $results) {
foreach ($results as $email => $r) {
echo "$email: {$r->status}\n";
}
});
PSR-6 Caching
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter('email-validator', 300);
$client = new Client('ev_...', cache: $cache);
// Account info auto-cached for 5 min
$account = $client->getAccount();
// Force refresh
$account = $client->getAccount(forceRefresh: true);
Type-Safe DTOs
| Class | Properties |
|---|---|
VerificationResult |
email, status, reason, confidence, mxServer, mxList, smtpResponse, sourceIp, durationMs, remainingCredits, isYahoo |
AccountInfo |
email, plan, planName, creditsRemaining, creditsUsed, creditsLimit, planType, subscriptionActive, subscriptionCancelled, subscriptionExpires, freeRemaining, totalRemaining, isAdmin |
CreditInfo |
hasCredits, creditsRemaining |
Each DTO has a static fromApiResponse(array) factory and toArray() serialization.
Practical predicates
| Method | Returns | Explanation |
|---|---|---|
isValid() | bool | status === 'valid' |
isInvalid() | bool | status === 'invalid' |
isRisky() | bool | status === 'risky' |
isCatchAll() | bool | status === 'catch_all' |
isDisposable() | bool | status === 'disposable' |
isDeliverable() | bool | valid || risky || catch_all |
costCredit() | bool | valid || invalid (consumes a credit) |
Laravel Integration
The package registers itself via Laravel auto-discovery. Just add your API key to .env:
EMAIL_VALIDATOR_API_KEY=ev_your_key
Now use dependency injection or the facade anywhere:
use NSoftware\EmailValidator\Client;
use EmailValidator; // Facade alias
class SignupController
{
public function store(Request $request, Client $validator)
{
$result = $validator->verify($request->email);
if (!$result->isDeliverable()) {
return back()->withErrors(['email' => 'Invalid email']);
}
// Create user...
}
}
// Or with the facade:
$result = EmailValidator::verify('user@example.com');
$account = EmailValidator::getAccount();
Error Handling
| Exception | HTTP | When |
|---|---|---|
AuthenticationException | 401/403 | Bad or missing API key |
RateLimitException | 429 | 60 req/min or hourly cap. $e->retryAfterSeconds |
NoCreditsException | 429 | Credits exhausted |
ApiException | -- | Network error, unexpected response |
try {
$result = $client->verify('user@example.com');
} catch (RateLimitException $e) {
sleep($e->retryAfterSeconds);
// retry
} catch (NoCreditsException $e) {
// prompt user to upgrade
} catch (ApiException $e) {
logger()->error("Validation failed: {$e->getMessage()}");
}
Package Contents
| Folder | Description |
|---|---|
src/Client.php | Main API client with sync & async methods |
src/Data/ | Immutable DTOs (VerificationResult, AccountInfo, CreditInfo) |
src/Exceptions/ | Typed exceptions with HTTP codes |
src/Laravel/ | Service provider, facade, publishable config |
tests/ | PHPUnit tests |
config/ | Laravel config (publish with artisan) |
v5.0.0 · MIT license · PHP 8.1+ · Guzzle 7 · PSR-6 / PSR-3