Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dns Laravel Package

spatie/dns

Fetch DNS records in PHP using dig. Query domains for A, AAAA, CNAME, MX, TXT, SRV and more, filter by type(s), and get structured record objects with handy accessors for record details.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require spatie/dns

No additional configuration is required for basic usage.

  1. First Use Case: Fetch all DNS records for a domain (e.g., google.com):

    use Spatie\Dns\Dns;
    
    $records = Dns::getRecords('google.com');
    dd($records); // Returns a collection of DNSRecord objects
    
  2. Key Classes:

    • Dns: Main facade for querying DNS records.
    • DNSRecord: Represents individual records (e.g., A, MX, TXT).
    • CouldNotFetchDns: Updated exception class (previously DnsException) now includes dig exit code for debugging.
    • DnsException: Legacy alias (deprecated in favor of CouldNotFetchDns).
  3. Where to Look First:

    • Documentation (official docs).
    • src/DnsServiceProvider.php (service provider setup).
    • src/Dns.php (core facade logic).
    • src/Exceptions/CouldNotFetchDns.php (updated exception with exit code).

Implementation Patterns

Common Workflows

1. Fetching Specific Record Types

Filter records by type (e.g., MX, TXT, A):

$mxRecords = Dns::getRecords('example.com')->whereType('MX');
$txtRecords = Dns::getRecords('example.com')->whereType('TXT');

2. Caching DNS Responses

Avoid repeated DNS lookups by caching results (e.g., for rate-limited APIs or slow DNS providers):

$records = Cache::remember("dns_records_{$domain}", now()->addHours(1), function () use ($domain) {
    return Dns::getRecords($domain);
});

3. Handling DNS Failures Gracefully

Use try-catch blocks for DNS resolution errors. Now leverages the updated CouldNotFetchDns exception:

try {
    $records = Dns::getRecords('nonexistent.example');
} catch (CouldNotFetchDns $e) {
    Log::error("DNS lookup failed for nonexistent.example. Exit code: {$e->getExitCode()}. Message: " . $e->getMessage());
    // Fallback logic (e.g., return cached data or default values)
}

4. Integration with Laravel Queues

Offload DNS lookups to background jobs (e.g., for bulk domain checks):

use Spatie\Dns\Jobs\GetRecords;

GetRecords::dispatch('example.com')
    ->afterCommit()
    ->onQueue('dns');

5. Custom DNS Providers

Extend the package to support custom DNS resolvers (e.g., internal DNS servers):

use Spatie\Dns\DnsProvider;

class CustomDnsProvider implements DnsProvider {
    public function getRecords(string $domain): array {
        // Implement custom logic (e.g., call internal API)
        return ['type' => 'A', 'data' => '192.0.2.1'];
    }
}

// Register in AppServiceProvider:
Dns::extend('custom', function () {
    return new CustomDnsProvider();
});

// Usage:
Dns::onProvider('custom')->getRecords('example.com');

6. Bulk DNS Lookups

Process multiple domains efficiently:

$domains = ['google.com', 'github.com', 'spatie.be'];
$results = collect($domains)->map(fn ($domain) => Dns::getRecords($domain));

7. Validation with DNS Records

Validate domain ownership via DNS (e.g., check for TXT records):

$txtRecords = Dns::getRecords($domain)->whereType('TXT');
$hasVerification = $txtRecords->contains(fn ($record) =>
    str_contains($record->data, 'verification-code=12345')
);

Integration Tips

Laravel Ecosystem

  • Laravel Scout: Use DNS records for custom search logic (e.g., prioritize domains with MX records).
  • Laravel Notifications: Validate sender domains via DNS before sending emails.
  • Laravel Policies: Restrict access based on DNS records (e.g., only allow domains with specific TXT entries).
  • Laravel Horizon: Monitor DNS job failures in real-time.

Testing

  • Mock Spatie\Dns\Dns in unit tests:
    $this->mock(Spatie\Dns\Dns::class, function ($mock) {
        $mock->shouldReceive('getRecords')
             ->with('example.com')
             ->andReturn(collect([new DNSRecord(['type' => 'A', 'data' => '1.1.1.1'])]));
    });
    

Performance

  • Batch Processing: Use Laravel's chunk() or cursor() for large datasets.
  • Parallel Requests: Leverage Spatie\Async for concurrent DNS lookups:
    use Spatie\Async\Parallel;
    
    Parallel::make($domains)->each(function ($domain) {
        return Dns::getRecords($domain);
    });
    

Gotchas and Tips

Pitfalls

  1. Rate Limiting:

    • Some DNS providers (e.g., public resolvers like Google's 8.8.8.8) throttle requests.
    • Solution: Use a dedicated DNS service (e.g., Cloudflare API) or implement exponential backoff:
      use Symfony\Component\Process\Exception\ProcessTimedOutException;
      
      try {
          $records = Dns::getRecords($domain);
      } catch (ProcessTimedOutException $e) {
          sleep(2); // Wait before retry
          retry();
      }
      
  2. TTL (Time-to-Live) Caching:

    • DNS records are cached by resolvers. Changes may take time to propagate.
    • Solution: Use Dns::flushCache() (if supported) or implement local caching with short TTLs.
  3. DNSSEC Validation:

    • The package may not validate DNSSEC-signed records by default.
    • Solution: Use a library like rubensworks/dnssec-validator for additional checks.
  4. Non-Standard Record Types:

    • Some record types (e.g., CAA, SRV) may not be parsed correctly.
    • Solution: Extend DNSRecord or pre-process raw data:
      $rawRecords = Dns::getRecords($domain, true); // Get raw output
      
  5. Local Development:

    • DNS queries may fail if /etc/hosts or C:\Windows\System32\drivers\etc\hosts overrides are present.
    • Solution: Test with a public domain (e.g., google.com) or mock DNS responses.
  6. Case Sensitivity:

    • Domain names are case-insensitive, but some DNS providers may return inconsistent results.
    • Solution: Normalize domains to lowercase:
      $domain = strtolower($domain);
      
  7. Exception Handling:

    • Updated: DnsException is now an alias for CouldNotFetchDns, which includes the dig exit code for better debugging.
    • Tip: Always catch CouldNotFetchDns for detailed error information:
      catch (CouldNotFetchDns $e) {
          Log::error("Exit code: {$e->getExitCode()}, Message: " . $e->getMessage());
      }
      

Debugging Tips

  1. Enable Verbose Output:

    Dns::enableVerboseOutput(); // Logs raw DNS queries/responses
    
  2. Check Underlying Process: The package uses exec() to call dig or nslookup. Verify these tools are installed:

    dig google.com
    nslookup google.com
    
  3. Inspect Raw Data: Access raw DNS output for debugging:

    $rawOutput = Dns::getRecords($domain, true);
    dd($rawOutput);
    
  4. Common Errors:

    • "Command not found": Ensure dig/nslookup is installed. Fix: Install via brew install bind (macOS) or apt-get install dnsutils (Linux).
    • Timeouts: Increase PHP's max_execution_time or use a faster DNS provider.
    • Permission Denied: Ensure the web server user has access to DNS tools.
    • Exit Code Debugging: Use the new CouldNotFetchDns exception to diagnose dig failures:
      catch (CouldNotFetchDns $e) {
          if ($e->getExitCode() === 1) {
              //
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope