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:

    composer require spatie/dns
    

    Ensure dig is installed on your system (Linux/MacOS/Windows with WSL). If not, the package falls back to PHP's dns_get_record().

  2. First Query:

    use Spatie\Dns\Dns;
    
    $dns = new Dns();
    $records = $dns->getRecords('example.com');
    
  3. Filter Records:

    // Get only A records
    $aRecords = $dns->getRecords('example.com', 'A');
    
    // Get multiple types
    $aAndMx = $dns->getRecords('example.com', ['A', 'MX']);
    

Key First Use Cases

  • Domain Validation: Verify if a domain resolves to expected IPs (e.g., during user signup).
  • Email Setup: Fetch MX records to validate email configurations.
  • Infrastructure Checks: Monitor DNS propagation or detect misconfigurations.

Implementation Patterns

Core Workflows

  1. Basic DNS Lookup:

    $dns = new Dns();
    $records = $dns->getRecords('google.com');
    foreach ($records as $record) {
        echo $record->host() . ' => ' . $record->type() . ': ' . $record->data() . "\n";
    }
    
  2. Handling Specific Record Types:

    // SRV records for VoIP services
    $srvRecords = $dns->getRecords('example.com', 'SRV');
    $srvRecords[0]->target(); // e.g., "sip.example.com"
    
    // TXT records for SPF/DKIM
    $txtRecords = $dns->getRecords('example.com', 'TXT');
    $txtRecords[0]->content(); // e.g., "v=spf1 include:_spf.example.com ~all"
    
  3. Custom Nameservers:

    $dns->useNameserver('8.8.8.8')->getRecords('example.com');
    
  4. Retry Logic for Unstable Networks:

    $dns->setRetries(3)->setTimeout(2)->getRecords('example.com');
    

Integration Tips

  • Service Providers: Bind the Dns instance to the container for global access:

    $this->app->singleton(Dns::class, function () {
        return new Dns();
    });
    
  • Artisan Commands: Create a command to debug DNS issues:

    use Spatie\Dns\Dns;
    
    class DebugDnsCommand extends Command {
        protected $signature = 'dns:debug {domain} {--type=}';
        public function handle(Dns $dns) {
            $records = $dns->getRecords($this->argument('domain'), $this->option('type'));
            $this->table(['Host', 'Type', 'Data'], $records);
        }
    }
    
  • Testing: Mock the Dns class or use a test nameserver (e.g., 127.0.0.1 with dnsmasq):

    $this->mock(Dns::class)->shouldReceive('getRecords')
        ->once()
        ->andReturn([new A('example.com', '192.0.2.1')]);
    
  • Caching: Cache results for non-critical checks (e.g., TTL-based caching):

    $records = Cache::remember("dns_{$domain}_{$type}", now()->addMinutes(5), function () use ($dns, $domain, $type) {
        return $dns->getRecords($domain, $type);
    });
    

Gotchas and Tips

Common Pitfalls

  1. Missing dig:

    • Symptom: CouldNotFetchDns exception with exit code 127.
    • Fix: Install dig (e.g., sudo apt-get install dnsutils on Ubuntu) or ensure PHP’s dns_get_record() is enabled in php.ini (extension=dns).
  2. IDN (Internationalized Domain Names):

    • Issue: Domains with non-ASCII characters (e.g., 例.测试) may fail if dig converts them to ASCII.
    • Fix: Use ->noIdnOut() to disable IDN conversion:
      $dns->noIdnOut()->getRecords('例.测试');
      
  3. Rate Limiting:

    • Issue: Aggressive polling may trigger rate limits on public nameservers.
    • Fix: Use setTimeout() and setRetries() to avoid hammering:
      $dns->setTimeout(3)->setRetries(2)->getRecords('example.com');
      
  4. Record-Specific Quirks:

    • TXT Records: May contain multiple values (e.g., SPF records). Use content() to get the raw string or parse manually.
    • CAA Records: Use flags(), tag(), and value() for validation:
      $caa = $dns->getRecords('example.com', 'CAA')[0];
      $caa->tag(); // e.g., "issue"
      $caa->value(); // e.g., "letsencrypt.org"
      
  5. Root/TLD Queries:

    • Issue: Querying . (root) or .com may return unexpected results.
    • Fix: Append a trailing dot or use a specific nameserver:
      $dns->useNameserver('a.root-servers.net')->getRecords('com.');
      

Debugging Tips

  • Verbose Output: Enable debug mode for dig by extending the Dig handler:

    class DebugDigHandler extends \Spatie\Dns\Handlers\Dig {
        protected function buildCommand(string $domain, ?string $type = null): string {
            return parent::buildCommand($domain, $type) . ' +dnssec +trace';
        }
    }
    $dns->useHandlers([new DebugDigHandler()]);
    
  • Exception Handling: Catch CouldNotFetchDns for graceful degradation:

    try {
        $records = $dns->getRecords('example.com');
    } catch (\Spatie\Dns\Exceptions\CouldNotFetchDns $e) {
        Log::warning("DNS lookup failed for example.com: {$e->getExitCode()}");
        // Fallback logic
    }
    

Extension Points

  1. Custom Handlers: Implement your own handler for specialized DNS queries (e.g., DNSSEC validation):

    class DnssecHandler extends \Spatie\Dns\Handlers\Handler {
        public function getRecords(string $domain, ?string $type = null): array {
            // Custom logic using `dnssec-dig` or similar
        }
    }
    $dns->useHandlers([new DnssecHandler()]);
    
  2. Macros for Records: Extend record functionality dynamically:

    \Spatie\Dns\Records\Record::macro('isValidIp', function () {
        return filter_var($this->ip(), FILTER_VALIDATE_IP) !== false;
    });
    $aRecord->isValidIp(); // true/false
    
  3. Factory for Parsing: Use the Factory to parse raw DNS output (e.g., from logs):

    use \Spatie\Dns\Support\Factory;
    $record = (new Factory())->guess('example.com. 300 IN A 192.0.2.1');
    

Configuration Quirks

  • PHP dns_get_record():

    • Pros: No external dependencies.
    • Cons: Limited record types (e.g., no SRV/TXT). Prefer dig for full support.
    • Note: Enable allow_url_fopen in php.ini if using remote nameservers.
  • Nameserver Selection:

    • Public nameservers (e.g., 8.8.8.8) may throttle requests. Use authoritative nameservers for critical checks:
      $dns->useNameserver('ns1.example.com');
      
  • TTL Handling:

    • Records include ttl() in seconds. Account for this in caching strategies:
      $ttl = $records[0]->ttl(); // e.g., 3600 (1 hour)
      Cache::forever("dns_{$domain}", $records); // Cache until TTL expires
      
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata