dacoto / laravel-domain-validation
A domain validator rule for Laravel
Fund package maintenance!
dacoto97
Installs: 133 406
Dependents: 0
Suggesters: 0
Security: 0
Stars: 20
Watchers: 1
Forks: 9
Open Issues: 0
pkg:composer/dacoto/laravel-domain-validation
Requires
- php: ^8.1
- illuminate/validation: ^10.0|^11.0|^12.0
Requires (Dev)
- phpunit/phpunit: ^10.0
README
A domain validator rule for Laravel 10.x and higher with optional DNS record verification.
Features
- Validates domain format using regex
- Optional DNS record checking (A, AAAA, CNAME, TXT, MX records)
- Verify DNS records resolve to expected values
- Fluent API for chaining multiple DNS checks
- String-based validation syntax support
- Designed for external domains with DNS records
Installation
composer require dacoto/laravel-domain-validation
Basic Usage
Simple Domain Validation
Validates that the input is a properly formatted domain:
use dacoto\DomainValidator\Validator\Domain; public function rules() { return [ 'domain' => ['required', 'string', new Domain], ]; }
String Syntax with DNS Checks
You can use the string syntax to check for the presence of DNS records:
public function rules() { return [ // Require DNS records to exist (any type) 'hostname' => ['required', 'domain:dns'], // Require MX records 'domain' => ['required', 'domain:mx'], // Require multiple DNS record types 'website' => ['required', 'domain:a,mx'], ]; }
Fluent API
For more control, use the fluent API:
use dacoto\DomainValidator\Validator\Domain; public function rules() { return [ // Check for DNS records 'hostname' => ['required', (new Domain)->requireDns()], // Check for MX records 'email_domain' => ['required', (new Domain)->requireMx()], // Chain multiple DNS checks 'website' => ['required', (new Domain)->requireA()->requireMx()], ]; }
DNS Record Type Checks
Available DNS Record Types
dns- Checks for presence of any DNS record (A, AAAA, CNAME, TXT, MX, NS, or SOA)a- IPv4 address recordsaaaa- IPv6 address recordscname- Canonical name recordstxt- Text recordsmx- Mail exchange records
Verifying DNS Records Match Expected Values
You can verify that DNS records resolve to specific values using the fluent API:
use dacoto\DomainValidator\Validator\Domain; public function rules() { return [ // Require A record pointing to specific IP 'domain' => ['required', (new Domain)->requireA('192.0.2.1')], // Require MX record pointing to specific mail server 'email_domain' => ['required', (new Domain)->requireMx('mail.example.com')], // Multiple checks with specific values 'website' => [ 'required', (new Domain) ->requireA('192.0.2.1') ->requireMx('mail.example.com') ], ]; }
Multiple Expected Values
When a domain has multiple DNS records of the same type (e.g., multiple A records for load balancing), the validator passes if ANY of the records match the expected value. You can chain multiple calls to verify multiple specific values:
public function rules() { return [ // Verify domain has BOTH specific IPs // (each requireA checks if that IP exists among the A records) 'cdn_domain' => [ 'required', (new Domain) ->requireA('104.16.132.229') ->requireA('104.16.133.229') ], // Example with Google's public DNS (dns.google.com) // which resolves to both 8.8.8.8 and 8.8.4.4 'google_dns' => [ 'required', (new Domain) ->requireA('8.8.8.8') // Passes if this IP is found ->requireA('8.8.4.4') // Also passes if this IP is found ], ]; }
Advanced Examples
Form Request Validation
use Illuminate\Foundation\Http\FormRequest; use dacoto\DomainValidator\Validator\Domain; class CreateWebsiteRequest extends FormRequest { public function rules() { return [ 'domain' => [ 'required', 'string', (new Domain)->requireA()->requireMx() ], ]; } }
Manual Validator
use Illuminate\Support\Facades\Validator; use dacoto\DomainValidator\Validator\Domain; $validator = Validator::make($request->all(), [ 'domain' => ['required', new Domain('mx', 'a')], ]); if ($validator->fails()) { return redirect()->back()->withErrors($validator); }
Conditional DNS Checks
use dacoto\DomainValidator\Validator\Domain; public function rules() { return [ 'domain' => [ 'required', (new Domain) ->requireA() ->when($this->check_email, function ($rule) { return $rule->requireMx(); }) ], ]; }
Error Messages
The validator provides specific error messages for different validation failures:
- Invalid format: "The {attribute} is not a valid domain."
- Missing DNS records: "The {attribute} must have valid {TYPE} records."
- Missing any DNS: "The {attribute} must have valid DNS records."
- Value mismatch: "The {attribute} must have a {TYPE} record pointing to {value}."
Custom Error Messages
You can customize error messages in your language files:
// resources/lang/en/validation.php return [ 'domain' => 'The :attribute must be a valid domain name.', 'domain_dns' => 'The :attribute must have valid :type DNS records.', 'domain_dns_any' => 'The :attribute must have valid DNS records configured.', 'domain_dns_value' => 'The :attribute must have a :type record pointing to :value.', ];
Requirements
- PHP 8.1 or higher
- Laravel 10.x or higher
Testing
Run the test suite:
composer test
The package includes comprehensive tests covering:
- ✅ Basic domain format validation
- ✅ String-based syntax (via constructor:
new Domain('a'),new Domain('a', 'mx')) - ✅ Fluent API methods (chaining, expected values)
- ✅ All DNS record types (A, AAAA, CNAME, TXT, MX, ANY)
- ✅ Multiple expected values (load balancing scenarios)
- ✅ Error messages and edge cases
- ✅ Uses reliable test domain (dns.google.com)
Test Results: 20 tests, 37 assertions, 100% passing ✅
License
This package is open-sourced software licensed under the MIT license.