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
composer require alyakin/dns-checkerphp artisan vendor:publish --tag=dns-checker-configuse Alyakin\DnsChecker\DnsLookupService;
$dns = new DnsLookupService(config('dns-checker'));
$ips = $dns->getRecords('example.com'); // A records
$txt = $dns->getRecords('example.com', 'TXT'); // TXT recordsIf 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,
]);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
}use Alyakin\DnsChecker\Facades\DnsChecker;
$ips = DnsChecker::getRecords('example.com', 'A');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.
use Alyakin\DnsChecker\Contracts\DnsLookup;
final class SomeJob
{
public function handle(DnsLookup $dns): void
{
$ips = $dns->getRecords('example.com', 'A');
}
}php artisan dns:check example.com AFile: 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).
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,
],// 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;
}
}composer test
composer pint
composer phpstanPre-commit hook (Pint → PHPStan → Pest):
git config core.hooksPath .githooksMIT