PHPackages                             webo3/smtp-email-validation - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. webo3/smtp-email-validation

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

webo3/smtp-email-validation
===========================

Comprehensive email validation: syntax, disposable domain detection, DNS checks, and SMTP verification with scoring.

v2.0.0(3mo ago)07MITPHPPHP &gt;=8.0

Since Feb 19Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/webo3/smtp-email-validation)[ Packagist](https://packagist.org/packages/webo3/smtp-email-validation)[ Docs](https://www.webo3.com)[ RSS](/packages/webo3-smtp-email-validation/feed)WikiDiscussions main Synced 2d ago

READMEChangelogDependencies (1)Versions (3)Used By (0)

smtp-email-validation
=====================

[](#smtp-email-validation)

Comprehensive PHP email validation library with syntax checking, disposable domain detection, DNS verification, SMTP mailbox validation, and a scoring system.

**Requires:** PHP 8.0+ with `fsockopen`, `getmxrr`, `dns_get_record` and ability to connect to remote port 25.

Installation
------------

[](#installation)

```
composer require webo3/smtp-email-validation
```

Usage
-----

[](#usage)

### Full Validation with Scoring (Recommended)

[](#full-validation-with-scoring-recommended)

```
use webO3\SmtpEmailValidation\EmailValidator;

$validator = new EmailValidator(
    fromEmail: 'noreply@yourdomain.com',
    validThreshold: 60,  // Score >= 60 considered valid
    timeout: 30,
);

$result = $validator->validate('user@example.com');

echo $result->score;    // 0-100
echo $result->isValid;  // true/false
echo $result->email;    // 'user@example.com'

// Per-check breakdown
foreach ($result->checks as $check) {
    echo "{$check->name}: {$check->status->value} (score: {$check->score})\n";
}

// Get a specific check
$smtpCheck = $result->getCheck('smtp');

// Convert to array (useful for JSON APIs)
$array = $result->toArray();
```

### Quick Static Method

[](#quick-static-method)

```
use webO3\SmtpEmailValidation\Validator;

// Full validation with scoring
$result = Validator::validate('user@example.com', from: 'noreply@yourdomain.com');
echo $result->score; // 0-100
```

### Custom Check Configuration

[](#custom-check-configuration)

Run only specific checks or adjust settings:

```
use webO3\SmtpEmailValidation\EmailValidator;
use webO3\SmtpEmailValidation\Check\SyntaxCheck;
use webO3\SmtpEmailValidation\Check\DisposableDomainCheck;
use webO3\SmtpEmailValidation\Check\DnsCheck;

// Lightweight validation without SMTP (no port 25 needed)
$validator = new EmailValidator(
    validThreshold: 50,
    checks: [
        new SyntaxCheck(),
        new DisposableDomainCheck(cacheTtl: 3600), // refresh list every hour
        new DnsCheck(),
    ],
);

$result = $validator->validate('user@example.com');
```

### Legacy SMTP-Only Check (Backward Compatible)

[](#legacy-smtp-only-check-backward-compatible)

```
use webO3\SmtpEmailValidation\Validator;

$response = Validator::test('noreply@yourdomain.com', 'user@example.com');
// Returns: ['code' => 250, 'success' => true, 'msg' => 'Email is valid', 'debug' => [...]]
```

Examples
--------

[](#examples)

Runnable example scripts are provided in the `examples/` directory:

```
# Full validation with score breakdown
php examples/basic-validation.php user@example.com

# Syntax-only check (no network calls)
php examples/syntax-only.php user@example.com

# Batch validation from arguments or file
php examples/batch-validation.php user1@gmail.com user2@mailinator.com
php examples/batch-validation.php --file emails.txt

# Custom checks (skip SMTP, JSON output)
php examples/custom-checks.php user@example.com
```

Validation Checks
-----------------

[](#validation-checks)

The library runs four checks in sequence:

CheckWeightDescription**Syntax**25%RFC 5322 format validation (local-part length, domain structure, etc.)**Disposable**15%Checks against a regularly updated list of disposable email providers**DNS**25%MX records, A-record fallback, SPF and DMARC presence**SMTP**35%Connects to mail server and verifies the mailbox existsIf syntax validation fails, all subsequent checks are skipped and the score is 0.

### Disposable Domain List

[](#disposable-domain-list)

The disposable domain check automatically fetches the latest list from the [disposable-email-domains](https://github.com/disposable-email-domains/disposable-email-domains) community project and caches it locally (default: 24 hours). If the fetch fails, a bundled fallback list is used.

You can configure the cache TTL and location:

```
new DisposableDomainCheck(
    cachePath: '/path/to/cache.json',  // default: sys_get_temp_dir()
    cacheTtl: 3600,                    // refresh every hour (default: 86400)
);
```

Scoring System
--------------

[](#scoring-system)

Each check produces a score from 0-100, weighted by importance:

- **Overall score** = weighted average of non-skipped checks (0-100)
- **isValid** = score &gt;= threshold (default: 60)

### Example Scores

[](#example-scores)

ScenarioScoreValid email, all checks pass100Valid email, disposable domain~85Valid email, SMTP greylisting (451/452)~79Valid email, SMTP rejected~65Invalid syntax0### DNS Sub-Scoring

[](#dns-sub-scoring)

DNS ComponentPointsMX records found40A-record fallback (no MX)20SPF record present30DMARC record present30### SMTP Sub-Scoring

[](#smtp-sub-scoring)

SMTP StagePointsConnected to MX server20Valid 220 greeting20RCPT TO accepted (250)60Greylisting (451/452)40Legacy Response Codes
---------------------

[](#legacy-response-codes)

When using `Validator::test()`:

CodeSuccessDescription10falseNo MX records found for domain15falseCould not connect to any MX servers20falseConnection timeout25falseServer did not return 220 greeting250trueEmail is valid451/452trueTemporary rejection (greylisting)OtherfalseEmail rejectedTesting
-------

[](#testing)

```
composer install
vendor/bin/phpunit
```

Warning
-------

[](#warning)

- Many hosting providers and ISPs block direct connections to remote port 25.
- Use a valid FROM address — some blacklists may block specific sender addresses.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance82

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~719 days

Total

2

Last Release

95d ago

Major Versions

v1.0.0 → v2.0.02026-02-08

PHP version history (2 changes)v1.0.0PHP &gt;=5.6

v2.0.0PHP &gt;=8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/0a175e082beae5946d428cc9e5675c903fe5df3691351b6db3ec22eb6b2ea1ab?d=identicon)[moihuguesjoyal](/maintainers/moihuguesjoyal)

---

Top Contributors

[![huguesjoyal](https://avatars.githubusercontent.com/u/16695693?v=4)](https://github.com/huguesjoyal "huguesjoyal (7 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/webo3-smtp-email-validation/health.svg)

```
[![Health](https://phpackages.com/badges/webo3-smtp-email-validation/health.svg)](https://phpackages.com/packages/webo3-smtp-email-validation)
```

###  Alternatives

[webmozart/assert

Assertions to validate method input/output with nice error messages.

7.6k894.0M1.2k](/packages/webmozart-assert)[bensampo/laravel-enum

Simple, extensible and powerful enumeration implementation for Laravel.

2.0k15.9M104](/packages/bensampo-laravel-enum)[nette/forms

📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server &amp; client side validation and mature design.

54013.2M450](/packages/nette-forms)[swaggest/json-schema

High definition PHP structures with JSON-schema based validation

48612.5M73](/packages/swaggest-json-schema)[stevebauman/purify

An HTML Purifier / Sanitizer for Laravel

5325.6M19](/packages/stevebauman-purify)[ashallendesign/laravel-config-validator

A package for validating your Laravel app's config.

217905.3k5](/packages/ashallendesign-laravel-config-validator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
