voku/email-check
Validates email addresses in PHP with multiple checks (syntax, DNS/MX, disposable domains and more) to reduce bounces and fake signups. Lightweight library with simple API, suitable for signup forms, user imports, and email hygiene workflows.
Installation
composer require voku/email-check
Add to composer.json if using a monorepo or constrained environment.
Basic Usage
use Voku\EmailCheck\EmailCheck;
$email = 'test@example.com';
$result = EmailCheck::check($email);
// Result structure:
// [
// 'valid' => bool,
// 'reason' => string|null,
// 'syntax' => bool,
// 'dns' => bool,
// 'disposable' => bool,
// 'trash' => bool,
// 'typo' => bool,
// 'suggestions' => array,
// ]
First Use Case Validate user input in a registration form:
$request->validate([
'email' => ['required', function ($attribute, $value, $fail) {
$result = EmailCheck::check($value);
if (!$result['valid']) {
$fail('Invalid email: ' . ($result['reason'] ?? 'unknown error'));
}
}]
]);
Bulk Validation
$emails = ['user1@example.com', 'invalid@test'];
$results = EmailCheck::checkMultiple($emails);
// Returns array of result objects
Async Validation (Queue Jobs)
// Dispatch a job for DNS-heavy checks
EmailCheckJob::dispatch($email)->onQueue('email-validation');
Integration with Laravel Forms
// Custom rule for form requests
use Illuminate\Validation\Rule;
$request->validate([
'email' => [
'required',
Rule::custom(function ($value) {
return EmailCheck::check($value)['valid'];
})
]
]);
Caching Results
// Cache DNS checks for 24h
$cacheKey = "email:{$email}:dns";
if (Cache::has($cacheKey)) {
$result['dns'] = Cache::get($cacheKey);
} else {
$result['dns'] = EmailCheck::checkDNS($email);
Cache::put($cacheKey, $result['dns'], now()->addHours(24));
}
Custom Suggestion Logic
$result = EmailCheck::check($email);
if ($result['typo']) {
$suggestions = EmailCheck::getSuggestions($email);
// Integrate with frontend for autocomplete
}
Disposable Email Blocking
if (EmailCheck::isDisposable($email)) {
return back()->withErrors('Disposable emails not allowed.');
}
Rate Limiting DNS Checks
// Throttle DNS queries to avoid abuse
$throttleKey = "email:dns:{$email}";
if (!RateLimiter::tooManyRequests($throttleKey, 10)) {
$result['dns'] = EmailCheck::checkDNS($email);
}
DNS Check Timeouts
checkDNS($email, 2) to limit timeout (seconds).False Positives for Trash Emails
checkTrash() may flag legitimate emails as "trash" if the domain is misconfigured.checkDNS() for accuracy:
$result['trash'] = EmailCheck::checkDNS($email) && EmailCheck::checkTrash($email);
Disposable Email Lists
EmailCheck::addDisposableDomains(['mailinator.com', 'tempmail.com']);
Case Sensitivity
EmailCheck::check() normalizes case, but some DNS checks may not.$email = strtolower($email);
Verbose Output
$result = EmailCheck::check($email, true); // Enable debug mode
dd($result); // Inspect all checks
DNS-Specific Errors
checkDNS() separately to isolate issues:
try {
$dnsResult = EmailCheck::checkDNS($email);
} catch (\Exception $e) {
// Log or handle DNS failure gracefully
}
Performance Profiling
$start = microtime(true);
$result = EmailCheck::check($email);
$time = microtime(true) - $start;
// Log $time for optimization
Custom Check Logic
// Add a custom validation rule
EmailCheck::addCheck('custom', function ($email) {
return str_contains($email, 'corp') && str_ends_with($email, 'company.com');
});
Override Default Providers
EmailCheck::setDisposableDomainsFile('/path/to/custom_list.txt');
Mocking for Tests
// In PHPUnit tests
EmailCheck::setMockDNS(true); // Disable real DNS checks
EmailCheck::setMockDNSResult($email, true); // Force pass/fail
Laravel Service Provider Bind the package to the container for dependency injection:
$this->app->singleton(EmailCheck::class, function () {
return new EmailCheck();
});
How can I help you explore Laravel packages today?