alyakin / dns-checker
This is a wrapper for pear/net_dns2 for fast managed DNS checking
Installs: 112
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/alyakin/dns-checker
Requires
- php: >=8.1
- pear/net_dns2: ^1.5.5 || ^2.0
Requires (Dev)
- illuminate/support: ^9.0 || ^10.0 || ^11.0
- laravel/pint: ^1.22
- pestphp/pest: ^3.8
- phpstan/phpstan: ^1.12
- phpunit/phpunit: ^11.5
README
A Laravel-friendly DNS lookup wrapper over pear/net_dns2 with:
- Custom DNS servers + optional fallback to the system resolver
- Optional typed exceptions (
throw_exceptions) - Optional NXDOMAIN logging control
- Optional Laravel Cache-backed caching (Redis/Memcached/Database/etc), avoiding netdns2 file/shmop cache pitfalls
- Facade, fluent API and DI support
Installation
composer require alyakin/dns-checker
Publish config (Laravel)
php artisan vendor:publish --tag=dns-checker-config
Usage
Plain usage
use Alyakin\DnsChecker\DnsLookupService; $dns = new DnsLookupService(config('dns-checker')); $ips = $dns->getRecords('example.com'); // A records $txt = $dns->getRecords('example.com', 'TXT'); // TXT records
If you are not in Laravel, pass the config array directly:
use Alyakin\DnsChecker\DnsLookupService; $dns = new DnsLookupService([ 'servers' => ['8.8.8.8'], 'timeout' => 2, 'retry_count' => 1, ]);
Error handling
By default (throw_exceptions=false) errors result in an empty array:
$records = $dns->getRecords('does-not-exist.example', 'A'); // []
With throw_exceptions=true, you can use try/catch:
use Alyakin\DnsChecker\Exceptions\DnsQueryFailedException; use Alyakin\DnsChecker\Exceptions\DnsRecordNotFoundException; use Alyakin\DnsChecker\Exceptions\DnsTimeoutException; try { $records = $dns->getRecords('does-not-exist.example', 'A'); } catch (DnsRecordNotFoundException $e) { // NXDOMAIN } catch (DnsTimeoutException $e) { // timeout } catch (DnsQueryFailedException $e) { // other DNS errors }
Facade (Laravel)
use Alyakin\DnsChecker\Facades\DnsChecker; $ips = DnsChecker::getRecords('example.com', 'A');
Fluent API (Laravel)
use Alyakin\DnsChecker\Facades\DnsChecker; $result = DnsChecker::usingServer('8.8.8.8') ->withTimeout(5) ->setRetries(3) ->query('example.com', 'TXT');
Notes:
usingServer()overridesserversfor this call; it will not try other configured servers.- System fallback may still happen if
fallback_to_system=true.
Dependency Injection (Laravel)
use Alyakin\DnsChecker\Contracts\DnsLookup; final class SomeJob { public function handle(DnsLookup $dns): void { $ips = $dns->getRecords('example.com', 'A'); } }
CLI (Laravel)
php artisan dns:check example.com A
Configuration
File: config/dns-checker.php
servers(array): DNS servers (IP/host) to query first.timeout(int|float): resolver timeout.retry_count(int): retry count (netdns2 v1 only; netdns2 v2 does not exposeretry_countas an option).fallback_to_system(bool, defaulttrue): whenserversare set and the result is empty, try the system resolver; iffalse, return empty result without system lookup.log_nxdomain(bool, defaultfalse): whether to callreport()on NXDOMAIN. Other DNS errors are still reported.throw_exceptions(bool, defaultfalse): iftrue, throw typed exceptions instead of returning[]and callingreport().domain_validator(string|null):"Class@method"validator ornullto disable validation. Default isAlyakin\\DnsChecker\\DomainValidator::class.'@validate'.cache(array):enabled(bool): enable Laravel Cache-backed caching for DNS results.store(string|null): cache store name fromconfig/cache.php(e.g.redis,file,database,memcached).nulluses the default store.ttl(int): TTL in seconds.prefix(string): cache key prefix.cache_empty(bool): cache empty NOERROR/NODATA responses (exceptions are not cached).
Laravel Cache example
If Redis is your default Laravel cache driver, just enable caching and keep store=null:
// config/dns-checker.php return [ // ... 'cache' => [ 'enabled' => true, 'store' => null, 'ttl' => 60, 'prefix' => 'dns-checker', 'cache_empty' => false, ], ];
To pin a specific store:
'cache' => [ 'enabled' => true, 'store' => 'redis', // or 'file' / 'database' / 'memcached' 'ttl' => 60, ],
Custom domain validator example
// config/dns-checker.php return [ // ... 'domain_validator' => \App\Support\Dns\DomainValidator::class.'@validate', ];
namespace App\Support\Dns; final class DomainValidator { public static function validate(string $domain): bool { return str_ends_with($domain, '.example') && filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) !== false; } }
Development
composer test
composer pint
composer phpstan
Pre-commit hook (Pint → PHPStan → Pest):
git config core.hooksPath .githooks
License
MIT