react/dns
Async DNS resolver for ReactPHP. Provides non-blocking hostname lookups with a simple ResolverInterface, optional caching, and advanced UDP/TCP transports and hosts file support. Also includes tools for working with DNS messages and building DNS servers.
Install via Composer: composer require react/dns. Start with the Factory to create a resolver using system-configured DNS servers (loaded blocking — do this once at bootstrap). For quick testing, pass a nameserver like '8.8.8.8' directly. The most common first use is resolving a hostname to a single IP with resolve() — returns a promise that resolves with the IP string or rejects with an exception on failure.
$factory = new React\Dns\Resolver\Factory();
$dns = $factory->createCached('8.8.8.8'); // Uses caching by default in `createCached`
$dns->resolve('example.com')->then(fn($ip) => echo "Resolved: $ip\n");
Key first steps:
Config::loadSystemConfigBlocking() repeatedly — call it once before the loop starts.createCached() over create() unless you explicitly need no caching.resolve() for simple A lookups; use resolveAll($host, Message::TYPE_* ) when you need multiple records (e.g., AAAA, MX).TimeoutExecutor, RetryExecutor, CoopExecutor) for robustness:$executor = new CoopExecutor(
new RetryExecutor(
new TimeoutExecutor(
new UdpTransportExecutor('8.8.8.8:53'),
3.0
)
)
);
$resolver = new Resolver($executor, $config);
ArrayCache for CLI scripts or request-scoped caching. For long-running processes (e.g., workers), consider persistent cache adapters like react/cache-redis to share lookups across processes.HostsFileExecutor for /etc/hosts resolution — no extra config needed. Ideal for dev/test environments or overriding production DNS.resolve() call is non-blocking:$hosts = ['a.com', 'b.com', 'c.com'];
$promises = array_map(fn($h) => $dns->resolve($h), $hosts);
all($promises)->then(fn($ips) => print_r($ips));
SelectiveTransportExecutor to automatically fall back to TCP on truncated UDP responses (e.g., for large DNSSEC responses).Config::loadSystemConfigBlocking() and HostsFileExecutor load files synchronously. Cache their results — don’t call them inside event callbacks.UdpTransportExecutor lacks timeouts and retries — always compose with TimeoutExecutor and RetryExecutor, or use createCached() which does this internally..cancel(), but DNS queries are tied to socket resources — uncancelled promises may hold open sockets.resolve() only returns IPv4 (A). Use resolveAll($host, Message::TYPE_AAAA) for IPv6. For SRV/MX, inspect Record objects in the answers array — don’t assume string IPs.(domain, type, class) uniqueness.MockExecutor or override config with '127.0.0.1' to avoid network calls in unit tests — write mocks that resolve with new Response(Message::CODE_NOERROR, ...).How can I help you explore Laravel packages today?