Download the PHP package harungecit/php-email-validator without Composer

On this page you can find all versions of the php package harungecit/php-email-validator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package php-email-validator

# PHP Email Validator **The most complete email validation & disposable email detection library for PHP.** One package for Laravel, Symfony, CodeIgniter 4, CakePHP, Yii 2, Yii 3, Phalcon — and plain PHP. [![PHP Version](https://img.shields.io/packagist/php-v/harungecit/php-email-validator?style=flat-square&logo=php&logoColor=white)](https://packagist.org/packages/harungecit/php-email-validator) [![Latest Version](https://img.shields.io/packagist/v/harungecit/php-email-validator?style=flat-square&logo=packagist&logoColor=white&label=version)](https://packagist.org/packages/harungecit/php-email-validator) [![Total Downloads](https://img.shields.io/packagist/dt/harungecit/php-email-validator?style=flat-square&logo=packagist&logoColor=white)](https://packagist.org/packages/harungecit/php-email-validator) [![CI Status](https://img.shields.io/github/actions/workflow/status/harungecit/php-email-validator/ci.yml?branch=main&style=flat-square&logo=github&logoColor=white&label=tests)](https://github.com/harungecit/php-email-validator/actions/workflows/ci.yml) [![List Updates](https://img.shields.io/github/actions/workflow/status/harungecit/php-email-validator/update-lists.yml?branch=main&style=flat-square&logo=github&logoColor=white&label=daily%20list%20update)](https://github.com/harungecit/php-email-validator/actions/workflows/update-lists.yml) [![License](https://img.shields.io/packagist/l/harungecit/php-email-validator?style=flat-square&logo=opensource&logoColor=white)](LICENSE) [![Blocklist Domains](https://img.shields.io/badge/blocklist-137,600%2B%20domains-red?style=flat-square&logo=shield&logoColor=white)](#-the-disposable-domain-list) [![Frameworks](https://img.shields.io/badge/frameworks-Laravel%20%7C%20Symfony%20%7C%20CodeIgniter%20%7C%20CakePHP%20%7C%20Yii%20%7C%20Phalcon-blue?style=flat-square)](#-framework-integrations) [![Platform Support](https://img.shields.io/badge/platform-Linux%20%7C%20Windows%20%7C%20macOS-blue?style=flat-square)](#compatibility)

Table of Contents


⭐ Why this package?

php-email-validator Typical disposable-list package
Disposable domains 137,600+ disposable domains, multi-source, daily rebuild one source, a few thousand to ~100k
False-positive protection Public Suffix List, popularity, typo & allowlist filters, regression tests none — aggregated feeds are merged blindly
Subdomain detection (x.mailinator.com) ✅ (configurable) sometimes
Explains matches (entry + source) ✅ checkDisposable() rarely
Runtime sync between releases ✅ append-only, atomic, locked, HTML-safe sometimes
Format: filter / unicode / RFC 5322 / strict ✅ framework-dependent
MX / DNS, spoof (homograph), role-based, plus-addressing, typo suggestions ✅ ❌
SMTP mailbox & catch-all verification ✅ (opt-in) ❌
Frameworks Laravel, Symfony, CodeIgniter 4, CakePHP, Yii 2, Yii 3, Phalcon, plain PHP usually one
CLI ✅ vendor/bin/email-validator framework-only, if any
Caching / rate limiting / PSR-3 logging ✅ Memory, File, Redis, Memcached, PSR-16 ❌
PHP versions 8.0 – 8.5 varies

Installation

Compatibility


🚀 Quick start

Just need a disposable check, no network?


🛡 Disposable email detection

How a domain is matched

The domain and each of its parent domains are looked up, most specific first — a.b.mailinator.com, b.mailinator.com, mailinator.com — so throwaway subdomains are caught too. On each level the lists are consulted in this order (first hit wins):

Priority List Source label
1 Your allowlist — lists.custom_allowlist, custom_allowlist_paths, addToAllowlist() allowlist
2 Your blocklist — lists.custom_blocklist, custom_blocklist_paths, addToBlocklist() custom
3 Bundled allowlist (237 legitimate providers, ISPs and privacy relays) allowlist
4 Synced blocklist (lists.synced_blocklist_path) synced
5 Bundled blocklist (or your replacement via lists.blocklist_path) blocklist

So your own decisions always win over the bundled data — e.g. you can block a privacy relay the package allows, or allow a domain the package blocks.

Lists can also be changed at runtime (fluent): addToBlocklist(), addToAllowlist(), removeFromBlocklist(), removeFromAllowlist(), getBlocklist(), getBlocklistCount(), isBlocklisted(), isAllowlisted(). Runtime changes never copy the shared index.

Privacy relays (Apple Hide My Email, Firefox Relay, DuckDuckGo, SimpleLogin, Proton Pass, addy.io) forward to a real inbox and are allowed by default. To block them, add them to your blocklist.


📚 The disposable domain list

The bundled list is rebuilt every day from multiple upstream projects and released as a patch version every Monday, so a regular composer update keeps you current. Want daily freshness? See sync.

Source Role Treatment
disposable-email-domains hand-curated, conservative trusted — taken as-is
eramitgupta/disposable-email large daily aggregator (several lists + StopForumSpam toxic domains) untrusted — every entry is filtered
data/blocklist.local.conf maintainers' additions always included
data/allowlist.conf legitimate domains always excluded (with subdomains)

Aggregated feeds contain real companies and ISPs that were once abused by spammers. Blindly merging them would block e.g. namecheap.com, yandex.net, sutterhealth.org, Roadrunner/Spectrum ISP addresses (nyc.rr.com) or entire country zones (msk.ru, pp.ua). The build therefore drops:

Filter Applies to Example of what it prevents
Invalid syntax / upstream merge artifacts all / untrusted btcmail.pwguerrillamail.net (two lines glued together)
Public Suffix List entries all msk.ru, pp.ua, it.com — would block every domain below them
Allowlisted domains and their subdomains all vip.126.com, simplelogin.co, nyc.rr.com
Tranco top-100k popular domains untrusted only namecheap.com, compaq.com, cafe24.com
Typos of major providers untrusted only gamil.com → handled by typo suggestions instead of a misleading "disposable" error

On top of that the build refuses to shrink the list by more than 5% in one run, switches to an additive (remove-nothing) mode if an untrusted source is down, and CI keeps regression tests for known false positives. Build details live in data/metadata.json and in the output of email-validator stats.

Found a missing domain or a false positive? See CONTRIBUTING.md — fixes are permanent.


🔄 Keeping the list fresh (sync)

Package releases are weekly; the list on main is rebuilt daily. The synchronizer downloads remote lists into a file in your app, and every validator configured with that file blocks those domains too — no deploy needed.

Schedule it (cron, Laravel scheduler, Symfony scheduler, …):

By default the synchronizer downloads this package's own filtered list from main (Configuration::DEFAULT_SYNC_URL), so you get the same false-positive protection. Use --url= (repeatable) or the sync.urls setting to add other plain-text or JSON lists.

Safeguards — a bad download never damages your last good list:

Programmatic use:


🔬 Full validation pipeline

validate() runs every enabled check and returns a ValidationResult:

Check Default What it does
format ✅ Syntax — see format modes
spoof ❌ Mixed-script / invisible characters per address part (needs ext-intl)
disposable ✅ Bundled + custom + synced lists, subdomain-aware
mx ✅ MX records (checkdnsrr), cached per domain
role_based ❌ admin@, info@, support@, … (configurable prefixes)
subaddress ❌ Plus addressing user+tag@ (warning + base_email metadata)
smtp ❌ Live mailbox check (RCPT TO) — slow, may be blocked
catch_all ❌ Detects domains that accept every address
typo_suggestion ❌ "Did you mean gmail.com?" — never fails validation

Presets

Preset Enabled checks
minimal() format
basic() format, disposable
standard() format, mx, disposable, typo suggestion
strict() format, mx, disposable, role-based, subaddress, typo suggestion, smtp, catch-all

strict() enables SMTP and catch-all verification, which open live connections and can be slow or blocked. For most applications standard() is the recommended starting point.

Format modes

Mode Engine Accepts
filter (default) FILTER_VALIDATE_EMAIL ASCII addresses
filter_unicode FILTER_VALIDATE_EMAIL + FILTER_FLAG_EMAIL_UNICODE internationalized local parts (jö[email protected])
rfc egulias/email-validator RFCValidation everything RFC 5322 allows
strict egulias/email-validator NoRFCWarningsValidation RFC 5322 without warnings (no quoted local parts, …)

Spoofing (homograph) detection

Individual checks

Batch validation


⚙ Configuration

Use the fluent builder, an array, or a PHP/JSON/YAML file — they all produce a Configuration.

Ready-made templates: config/emailvalidator.json.

All configuration keys | Key | Default | Description | |---|---|---| | `checks.format` / `mx` / `disposable` | `true` | Core checks | | `checks.role_based` / `smtp` / `typo_suggestion` / `subaddress` / `catch_all` / `spoof` | `false` | Optional checks | | `format.mode` | `filter` | `filter`, `filter_unicode`, `rfc`, `strict` | | `lists.blocklist_path` / `allowlist_path` | `null` | **Replace** the bundled lists | | `lists.custom_blocklist` / `custom_allowlist` | `[]` | Domains **added** to the lists (take precedence over bundled lists) | | `lists.custom_blocklist_paths` / `custom_allowlist_paths` | `[]` | Extra list files or directories | | `lists.synced_blocklist_path` | `null` | File maintained by `sync` (ignored until it exists) | | `lists.block_subdomains` | `true` | Match parent domains (`x.mailinator.com` → `mailinator.com`) | | `lists.role_based_path` | `null` | Custom role-prefix list file | | `sync.urls` | package list on `main` | Remote lists for `sync` (text or JSON, http/https only) | | `sync.timeout` | `30` | HTTP timeout in seconds | | `cache.driver` / `ttl` / `prefix` / `options` | `memory`, `3600` | `memory`, `file`, `redis`, `memcached`, `psr16`, `null` | | `rate_limit.enabled` / `max_attempts` / `decay_seconds` | `false`, `100`, `60` | Token-bucket limiter | | `role_based.prefixes` | 36 prefixes | Role-account local parts | | `typo.common_domains` / `typo.mappings` | major providers | Typo suggestion data | | `smtp.timeout` / `from_email` / `from_domain` | `10`, `null`, `null` | SMTP verification | | `dns.timeout` | `5` | DNS timeout |

🧩 Framework integrations

Every integration wraps the same core, so behaviour and configuration keys are identical everywhere.

Framework Validation Services Commands / sync Extras
Laravel 9–13 rule objects + string rules facade, container Artisan, scheduler Blade directive, translations, Laravel Boost
Symfony 6.4–8 #[NotDisposableEmail], #[ValidEmail], #[NotRoleBasedEmail] autowiring bin/console YAML config, Scheduler
CodeIgniter 4.4+ auto-registered rules service('emailValidator') CLI + cron zero-config discovery, .env
CakePHP 4.4+/5 validation provider DI plugin CLI + cron Configure key
Yii 2 model validators app component CLI + cron aliases, Yii::t() messages
Yii 3 attribute rules DI container CLI + cron —
Phalcon 5 validators DI service provider CLI + cron config service section

Laravel

Supports Laravel 9–13 (rule objects need Laravel 10+). The service provider and the EmailValidator facade are auto-discovered.

Validation rules

Messages live in the emailvalidator::validation translation group (php artisan vendor:publish --tag=emailvalidator-translations). Rule-object messages accept :attribute; NotDisposableEmail also :domain and :matched, ValidEmail also :reason and :suggestion.

Facade, Blade & commands

Configuration (config/emailvalidator.php, env-aware; the cache driver defaults to your Laravel cache store):

Set EMAIL_VALIDATOR_SYNC_SCHEDULE=daily and the package registers email-validator:sync on Laravel's scheduler (withoutOverlapping()). AI agents using Laravel Boost get this package's guidelines automatically.

Symfony

Supports Symfony 6.4, 7.x and 8.x.

Message parameters: {{ value }}, {{ domain }}, {{ matched }} (NotDisposableEmail); {{ check }}, {{ reason }}, {{ suggestion }} (ValidEmail), with one error code per failed check. Services: EmailValidator (autowirable, alias email_validator), Configuration, ListSynchronizer (email_validator.synchronizer).

CodeIgniter 4

Zero configuration. CodeIgniter's auto-discovery picks up the package's Config/Registrar.php and Config/Services.php: the rules are added to Config\Validation::$ruleSets and service('emailValidator') returns a shared validator.

Rule Fails when
not_disposable_email the domain (or a parent domain) is disposable
email_has_mx the domain has no MX record
not_role_based_email the address is a role account (admin@, info@, …)
not_subaddressed_email the address has a +tag
not_spoofed_email it mixes scripts or has invisible characters (needs ext-intl)
verified_email the full configured pipeline fails; the message names the failed check

Messages ship as language lines ({field}, {value} and per-field custom errors work); override them in app/Language/<locale>/Validation.php. Use permit_empty for optional fields.

To configure, create app/Config/EmailValidator.php (properties mirror the configuration keys; .env overrides such as emailvalidator.checks.mx = false work too):

Discovery disabled? Add \HarunGecit\EmailValidator\Framework\CodeIgniter\EmailValidatorRules::class to Config\Validation::$ruleSets. Sync from cron: vendor/bin/email-validator sync --path=writable/email-validator/synced.conf.

CakePHP

Rules: notDisposable, notRoleBased, notSubaddressed, notSpoofed, hasMx, verifiedEmail (full pipeline). Manual use works as with any provider: ->setProvider('emailValidator', new EmailValidationProvider())->add('email', 'notDisposable', ['rule' => 'notDisposable', 'provider' => 'emailValidator']).

Register the plugin to get EmailValidator/Configuration in the DI container, configured from the EmailValidator key:

Yii 2

Messages support {attribute}, {value}, {domain}, {matched} (and {check}, {error}, {suggestion} for VerifiedEmailValidator) and go through Yii::t('app', …).

Yii 3

Handlers receive EmailValidator from the DI container — register it with your configuration:

Phalcon 5

Plain PHP / any framework

The core has no framework dependency: create an EmailValidator, keep it in your container, and use vendor/bin/email-validator sync from cron. Slim, Mezzio, Laminas, Lumen, Nette, Spiral, WordPress plugins — anything with Composer works.


💻 Command line

Exit codes: 0 = nothing flagged, 1 = disposable/invalid found or sync failed, 2 = usage error — handy for shell scripts and CI (e.g. validating a CSV export).


⚡ Performance


Caching, rate limiting & logging

Rate limiting throttles validations per address with a token bucket that shares the cache backend (works across processes with Redis/Memcached/File):

PSR-3 logging: $validator->setLogger($logger) or $config->setLogger($logger) — each validate() logs a debug entry with the outcome, checks and errors.


📖 Result objects & API reference

ValidationResult `isValid, getEmail, getDomain, getLocalPart, getChecks, passed(check), getErrors, getFirstError, getWarnings, isDisposable, isRoleBased, isSubaddressed, getMetadata, getMetadataValue, hasSuggestion, getSuggestion, toArray, toJson`. Metadata keys: `disposable_match`, `disposable_source`, `subaddressed`, `base_email`.
DisposableCheckResult `getInput, getDomain, isDisposable, getMatchedDomain, getSource, isAllowlisted, isSubdomainMatch, toArray, jsonSerialize`. Source constants: `SOURCE_BLOCKLIST`, `SOURCE_CUSTOM`, `SOURCE_SYNCED`, `SOURCE_ALLOWLIST`.
SuggestionResult `getOriginalEmail, getSuggestedEmail, getOriginalDomain, getSuggestedDomain, getReason, getConfidence, isHighConfidence, toArray, __toString`.
EmailValidator | Method | Description | |--------|-------------| | `create()` / `withConfig($c)` / `fromConfigFile($path)` / `strict()` / `basic()` | Factories | | `validate($email): ValidationResult` | Full pipeline | | `isValid($email, ?bool $checkMX = null): bool` | Boolean validation | | `validateBatch($emails)` | `array` | | `checkDisposable($emailOrDomain): DisposableCheckResult` | Explained disposable lookup | | `isDisposable($email)` / `isDisposableDomain($domain)` | Disposable checks | | `isValidFormat / hasValidMX / hasValidDNS / isSpoofed / isRoleBased / isSubaddressed / getBaseEmail / getSuggestion / isCatchAll / validateSMTP` | Individual checks | | `getListStatistics(): array` | Counts, sources, last sync, index strategy | | `addToBlocklist / addToAllowlist / removeFrom* / getBlocklist / getAllowlist / get*Count / isBlocklisted / isAllowlisted` | List management | | `validateMultiple / validateWithDetails / filterValid / filterInvalid / getStatistics` | 2.x-compatible helpers | | `extractDomain / extractLocalPart / normalize / normalizeMultiple` | Utilities | | `setConfiguration / getConfiguration / setLogger / setCacheEnabled / clearCache` | Runtime |
ConfigurationBuilder Presets `strict/standard/basic/minimal`; cache `withMemoryCache/withFileCache/withRedisCache/withMemcachedCache/withPsr16Cache/withCache/withoutCache`; `withRateLimiting/withoutRateLimiting`; checks `withRoleBasedCheck/withTypoSuggestion/withSmtpCheck/withSubaddressCheck/withCatchAllCheck/withSpoofCheck/withoutMxCheck/withoutDisposableCheck`; format `withFormatMode`; lists `withBlocklist/withAllowlist/withCustomBlocklist/withCustomAllowlist/withCustomBlocklistFiles/withCustomAllowlistFiles/withSyncedBlocklist/withoutSubdomainBlocking`; `build()`.
Fetcher (list files) `loadBlocklist, loadAllowlist, loadAll, loadBlocklistIndex, loadAllowlistIndex, loadCustomBlocklist, loadCustomAllowlist, loadPaths, mergeLists, saveList, compileIndex, getMetadata, clearCache, getBlocklistPath, getBlocklistIndexPath, getAllowlistPath, getMetadataPath, blocklistExists, allowlistExists, getBlocklistCount, getAllowlistCount, isOpcacheActive`.
Exceptions All extend `HarunGecit\EmailValidator\Exceptions\EmailValidatorException`: `RateLimitExceededException` (`getRetryAfter()`, `getMaxAttempts()`), `InvalidEmailException`, `ConfigurationException` (invalid value, unsupported format, missing file or dependency), `CacheException`, `SmtpConnectionException`.

Testing

The library runs on PHP 8.0+; the test suite needs PHP 8.1+ (PHPUnit 10–12). CI runs PHP 8.1 – 8.5 on Ubuntu, Windows and macOS, the oldest supported framework versions on PHP 8.1, a PHP 8.0 runtime smoke test, and data-integrity checks on every push.


Upgrading

3.2 is backward compatible with 3.0/3.1 and the 2.x API. Worth knowing:

Coming from 1.x? The namespace changed from PHPOrbit\EmailValidator to HarunGecit\EmailValidator, and the package from phporbit/php-email-validator to harungecit/php-email-validator.


Contributing

Contributions are welcome — missing disposable domains, false-positive reports, framework integrations and docs. Please read CONTRIBUTING.md; security issues go through SECURITY.md.

License

MIT — see LICENSE. The disposable domain data is derived from disposable-email-domains (CC0) and eramitgupta/disposable-email (MIT); thanks to their maintainers and to the Public Suffix List and Tranco projects.

Author

Harun Geçit — GitHub · LinkedIn · Email

If this package saves you from fake sign-ups, please ⭐ the repository — it helps other PHP developers find it.


Changelog

Automated weekly data releases (blocklist updates) are documented on the Releases page.

v3.2.0

v3.1.1

v3.1.0

v3.0.1

v3.0.0

v2.0.0

v1.0.x


All versions of php-email-validator with dependencies

PHP Build Version
Package Version
Requires php Version >=8.0
ext-filter Version *
psr/log Version ^1.0|^2.0|^3.0
psr/simple-cache Version ^1.0|^2.0|^3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package harungecit/php-email-validator contains the following files

Loading the files please wait ...