utopia-php / dns
Lite & fast micro PHP DNS server abstraction that is **easy to use**.
Installs: 14 377
Dependents: 1
Suggesters: 0
Security: 0
Stars: 4
Watchers: 6
Forks: 0
Open Issues: 1
pkg:composer/utopia-php/dns
Requires
- php: >=8.3
- utopia-php/console: 0.0.*
- utopia-php/domains: 0.9.*
- utopia-php/telemetry: 0.1.*
- utopia-php/validators: ^0.0.2
Requires (Dev)
- laravel/pint: 1.25.*
- phpstan/phpstan: 2.0.*
- phpunit/phpunit: 12.4.*
- swoole/ide-helper: 5.1.8
- dev-main
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.0
- 0.6.0
- 0.5.1
- 0.5.0
- 0.4.0
- 0.3.0
- 0.2.4
- 0.2.3
- 0.2.2
- 0.2.1
- 0.2.0
- 0.1.0
- dev-fix-resolver-answers
- dev-fix-lowercase-questions
- dev-feat-add-dns-validator
- dev-chore-downgrade-php8.7
- dev-feat-v2
- dev-fix-name-compression-rfc-1035
- dev-chore-remove-cli
- dev-feat-add-CAA-to-client
- dev-feat-worker-start-log
- dev-feat-benchmark-scripts
- dev-dev
- dev-feat-di
- dev-feat-zone-class
This package is auto-updated.
Last update: 2025-11-06 19:09:32 UTC
README
Utopia DNS is a modern PHP 8.3 toolkit for building DNS servers and clients. It provides a fully-typed DNS message encoder/decoder, pluggable resolvers, and telemetry hooks so you can stand up custom authoritative or proxy DNS services with minimal effort.
Although part of the Utopia Framework family, the library is framework-agnostic and can be used in any PHP project.
Installation
composer require utopia-php/dns
The library requires PHP 8.3+ with the ext-sockets extension. The Swoole adapter additionally needs the ext-swoole extension.
Quick start
Create an authoritative DNS server by wiring an adapter (UDP socket implementation) and a resolver (how records are answered). The example below uses the native PHP socket adapter and the in-memory zone resolver.
<?php require __DIR__ . '/vendor/autoload.php'; use Utopia\DNS\Adapter\Native; use Utopia\DNS\Message\Record; use Utopia\DNS\Resolver\Memory; use Utopia\DNS\Server; use Utopia\DNS\Zone; $adapter = new Native('0.0.0.0', 5300); $zone = new Zone( name: 'example.test', records: [ new Record(name: 'example.test', type: Record::TYPE_A, rdata: '127.0.0.1', ttl: 60), new Record(name: 'www.example.test', type: Record::TYPE_CNAME, rdata: 'example.test', ttl: 60), new Record(name: 'example.test', type: Record::TYPE_TXT, rdata: '"demo record"', ttl: 60), ], soa: new Record( name: 'example.test', type: Record::TYPE_SOA, rdata: 'ns1.example.test hostmaster.example.test 1 7200 1800 1209600 3600', ttl: 60 ), ); $server = new Server($adapter, new Memory($zone)); $server->setDebug(true); $server->start();
The server listens on UDP port 5300 and answers queries for example.test from the in-memory zone. Implement the Utopia\DNS\Resolver interface to serve records from databases, APIs, or other stores.
Resolvers
Memory: authoritative resolver backed by aZoneobjectProxy: forwards queries to another DNS serverCloudflare: proxy resolver preconfigured for1.1.1.1/1.0.0.1Google: proxy resolver preconfigured for8.8.8.8/8.8.4.4
Resolvers can be combined with any adapter. Implementing the Resolver interface allows you to plug in custom logic while reusing the message encoding/decoding and telemetry tooling.
Adapters
Native: pure PHP UDP server based onext-socketsSwoole: non-blocking server built on the Swoole UDP runtime
Adapters are responsible only for receiving and returning raw packets. They call back into the server with the payload, source IP, and port so your resolver logic stays isolated.
DNS client
The bundled client can query any DNS server and returns fully decoded messages.
<?php require __DIR__ . '/vendor/autoload.php'; use Utopia\DNS\Client; use Utopia\DNS\Message; use Utopia\DNS\Message\Question; use Utopia\DNS\Message\Record; $client = new Client('1.1.1.1'); $query = Message::query( new Question('example.com', Record::TYPE_A) ); $response = $client->query($query); foreach ($response->answers as $answer) { echo "{$answer->name} {$answer->ttl} {$answer->getTypeName()} {$answer->rdata}\n"; }
Telemetry
Server::setTelemetry() accepts any adapter from utopia-php/telemetry. Counters (dns.queries.total, dns.responses.total) and a histogram (dns.query.duration) are emitted automatically, enabling Prometheus or OpenTelemetry pipelines with minimal configuration.
Development
- Install dependencies:
composer install - Static analysis:
composer check - Coding standards:
composer lint(usecomposer formatto auto-fix) - Tests:
composer test - Sample Swoole server for manual testing:
docker compose up
Benchmarking
Run the bundled benchmark tool to measure throughput against your server:
php tests/benchmark.php --server=127.0.0.1 --port=5300 --iterations=1000 --concurrency=20
The script reports requests per second, latency distribution, and error counts across common record types.
License
MIT