Weave 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

Laravel Whois Laravel Package

larva/laravel-whois

A Laravel package for performing WHOIS domain lookups through a clean, expressive API. Retrieve registrar, registration and expiration details, with configurable caching and support for multiple TLDs. Easily integrate domain ownership checks into any Laravel application.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a thin wrapper around a PHP WHOIS client (typically io-developer/php-whois) exposed through a Laravel service provider and facade. Install it and wire it up:

composer require larva/laravel-whois

As of 1.2.9 the package declares support for Laravel 12 (alongside the earlier versions it already covered), so you can install it on a current Laravel app without a composer.json conflict. If you're on Laravel 12 and Composer still resolves an older tag, require it explicitly:

composer require larva/laravel-whois:^1.2.9

If the service provider is not auto-discovered (older Laravel), register Larva\Whois\WhoisServiceProvider in config/app.php and alias the facade. Publish any bundled config if present:

php artisan vendor:publish --provider="Larva\Whois\WhoisServiceProvider"

Where to look first: the README on the repo, then vendor/larva/laravel-whois/src/ to confirm the actual method names — with a handful of stars and 0 dependents, the API surface is small but not widely documented. Skim the facade and the response class before assuming method names. After a Laravel major bump like this one, also glance at the package's composer.json in vendor/ to confirm the illuminate/* constraints actually match your installed framework version.

First use case — a domain availability check:

use Larva\Whois\Whois; // verify namespace in vendor/

$result = Whois::lookup('example.com');

if ($result->isAvailable()) {
    // domain looks free
}

Wrap this call in try/catch immediately. WHOIS is a network operation against upstream registries; it fails regularly. Treat the first successful lookup as a smoke test that DNS, socket timeouts, and egress from your environment all work.

Implementation Patterns

Availability check service. Do not call the facade from controllers or Blade. Wrap it in a small application service so you can swap out the package, mock it in tests, and normalize its response:

class DomainLookup
{
    public function isAvailable(string $domain): ?bool
    {
        try {
            $r = Whois::lookup($domain);
            return $r->isAvailable() ? true : false;
        } catch (\Throwable $e) {
            report($e);
            return null; // "unknown" — don't tell users it's available
        }
    }
}

The tri-state (true/false/null) matters: "unknown" is the correct answer when the WHOIS server times out or returns a rate-limit page.

Cache aggressively. WHOIS registries throttle and occasionally block IPs. Cache by domain:

return Cache::remember("whois:{$domain}", now()->addHours(6), fn () =>
    $this->isAvailable($domain)
);

Six to twelve hours is reasonable for availability; use shorter TTLs (minutes) only when you're racing a user through checkout.

Queue bulk checks. For domain-search UIs ("check 20 TLDs at once") or monitoring jobs, dispatch one job per domain rather than looping in a request:

foreach ($domains as $d) {
    CheckDomainJob::dispatch($d)->onQueue('whois');
}

Set a low concurrency on that queue (1–2 workers) so you don't hammer a single registrar. Remember that Laravel 12 defaults to a leaner queue setup — if you're on database queues, make sure the whois queue is actually being consumed by a worker (--queue=whois,default).

Integrate into form validation. A common pattern is a custom rule:

class DomainAvailable implements ValidationRule
{
    public function validate(string $attr, mixed $value, \Closure $fail): void
    {
        if (app(DomainLookup::class)->isAvailable($value) === false) {
            $fail('This domain is not available.');
        }
    }
}

Note the strict === false — unknown results should not block validation, only confirmed-taken ones.

Expiry / registration data. If the response object exposes parsed fields (registrar, created/expiry dates), normalize them into a DTO early. The upstream client parses free-text WHOIS responses, which are inconsistent across TLDs; keeping your own DTO insulates the rest of your app from format drift.

Gotchas and Tips

  • TLD coverage is uneven. The underlying client only works for TLDs it has server entries for. .com, .net, .org are reliable; newer gTLDs (*.app, *.dev) and ccTLDs vary. Test every TLD you actually offer before launching.
  • "Available" is often inferred, not stated. Many registrars return No match for ... or an empty record for unregistered domains. The parser may or may not catch this. Verify against whois.iana.org output for the specific TLD.
  • Rate limits are per-registrar, not per-user. Shared hosting, Forge/Vapor IPs, and CI runners are frequently rate-limited by Verisign and friends. If you see empty responses, you're being throttled, not getting a real answer.
  • Timeouts are your default failure mode. Socket connects to port 43 can hang. Set a short timeout (5–10s) in your service class and never let a WHOIS call block a synchronous web request without one.
  • GDPR redaction. Contact data in .com/.net responses has been redacted since 2018; don't build a feature that assumes you can get registrant names.
  • Testing. The package ships no test doubles. Inject the facade's response class (or your own DomainLookup interface) so you can return fake responses in feature tests. Hitting the real network in CI is flaky and slow. If you're validating the Laravel 12 upgrade itself, run an integration test that does one real lookup plus a mocked suite — a version bump can change discovery/binding behaviour even when the wrapper "looks" unchanged.
  • Laravel 12 upgrade checks. 1.2.9 is a compatibility release (release note: 支持 Laravel 12), not a feature release — treat it as a low-risk bump, but after upgrading: clear config:cache and package:discover, and confirm the service provider still registers cleanly under Laravel 12's slimmer bootstrap. If you use Laravel's new default app skeleton, there's no config/app.php providers array to fall back on, so auto-discovery must work.
  • Maintenance signal is still thin but active. Small star count, 0 dependents, and thin documentation — however 1.2.9 shows the maintainer is still tracking Laravel majors. Pin the version (^1.2.9) in composer.json and be prepared to fork or replace with direct io-developer/php-whois calls if it goes stale — the wrapper is thin enough that extraction is trivial.
  • Extension points are limited. Because it's a wrapper, the only real customization is swapping the underlying client via the container binding, or forking. Don't expect pluggable parsers or TLD config beyond what's bundled.
  • Debugging tip. When a lookup returns something unexpected, dump the raw response content (the underlying client exposes the raw text on the response object). Comparing raw text against a manual whois example.com from your shell is the fastest way to tell whether the bug is in your code, the parser, or the registrar's response.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core