egulias/EmailValidator · error · \LogicException

The %s class requires the Intl extension.

Error message

The %s class requires the Intl extension.

What it means

SpoofCheckValidation uses the Spoofchecker class from the Intl (ICU) extension to detect visually confusable / mixed-script email addresses (a phishing technique). Its constructor throws a LogicException when extension_loaded('intl') is false, because the Spoofchecker API it calls in isValid() does not exist without that extension. Note it checks the extension itself while DNSCheckValidation checks the idn_to_ascii function — same root cause, different probe.

Source

Thrown at src/Validation/Extra/SpoofCheckValidation.php:21

namespace Egulias\EmailValidator\Validation\Extra;

use \Spoofchecker;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Result\SpoofEmail;
use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Validation\EmailValidation;

class SpoofCheckValidation implements EmailValidation
{
    /**
     * @var InvalidEmail|null
     */
    private $error;

    public function __construct()
    {
        if (!extension_loaded('intl')) {
            throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
        }
    }

    public function isValid(string $email, EmailLexer $emailLexer) : bool
    {
        $checker = new Spoofchecker();
        $checker->setChecks(Spoofchecker::SINGLE_SCRIPT);

        if ($checker->isSuspicious($email)) {
            $this->error = new SpoofEmail();
        }

        return $this->error === null;
    }

    public function getError() : ?InvalidEmail
    {
        return $this->error;

View on GitHub (pinned to d42c8731f0)

Solutions

  1. Install and enable the Intl extension: Debian/Ubuntu `apt-get install php-intl`, Alpine `apk add php83-intl`, Docker `docker-php-ext-install intl`; verify with `php -m | grep intl` in the exact SAPI (cli vs fpm) that runs your code.
  2. If spoof checking is a nice-to-have, gate it on extension availability: build the validation list with `extension_loaded('intl') ? new SpoofCheckValidation() : new RFCValidation()` so missing intl degrades gracefully.
  3. Remove SpoofCheckValidation from the validation set if the environment cannot have intl and spoof detection is not required — RFCValidation/NoRFCWarningsValidation cover syntax and RFC compliance without it.

Example fix

// before
$validations = [
    new RFCValidation(),
    new SpoofCheckValidation(), // throws LogicException without ext-intl
];

// after
$validations = [new RFCValidation()];
if (extension_loaded('intl')) {
    $validations[] = new SpoofCheckValidation();
}
Defensive patterns

Strategy: validation

Validate before calling

$validations = [new RFCValidation()];
if (extension_loaded('intl')) {
    $validations[] = new SpoofCheckValidation();
}
return new MultipleValidationWithAnd($validations);

Type guard

function canUseSpoofCheckValidation(): bool
{
    return extension_loaded('intl') && class_exists(\Spoofchecker::class);
}

Try / catch

try {
    $validation = new SpoofCheckValidation();
} catch (\LogicException $e) {
    // Intl extension missing: skip spoof checking rather than crashing validation
    $validation = new RFCValidation();
}

Prevention

When it happens

Trigger: Instantiating `new SpoofCheckValidation()` on a PHP build without ext-intl, e.g. `new EmailValidator()->isValid($email, new SpoofCheckValidation())`. Very commonly indirect: adding spoof checking to a combined validator `new MultipleValidationWithAnd([new RFCValidation(), new SpoofCheckValidation()])` — the composite constructor itself is fine, but PHP instantiates the argument list eagerly, so the LogicException fires on the same line. Deploying with `composer install --ignore-platform-reqs` when composer.json suggests ext-intl also surfaces this only at runtime.

Common situations: Hardening an existing email validator with spoof/phishing checks on a server that never needed intl before; alpine/slim Docker base images; CI green (unit tests mock or skip it) while production throws; hosts where ext-intl exists in CLI but is disabled in the FPM/php.ini used by the web server.

Related errors


AI-assisted analysis of egulias/EmailValidator@d42c8731f0 (2026-08-21). Data as JSON: /api/errors/379ec4bb6eed84b2. Report an issue: GitHub.