Skip to content

Commit 9817993

Browse files
authored
Merge pull request #3 from XternalSoft/feat/cli-refactor-and-iana-sync
feat(cli): refactor CLI entry point and synchronize WHOIS server list
2 parents 4ead8b4 + e9d7c18 commit 9817993

4 files changed

Lines changed: 6035 additions & 1434 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
PHP WHOIS client implementation. Sends the queries directly to the WHOIS services.
77

8-
> **Project Origin**: This project is a maintained fork of [xternalsoft/php-whois](https://github.com/xternalsoft/php-whois).
8+
> **Project Origin**: This project is a maintained fork of [io-developer/php-whois](https://github.com/io-developer/php-whois).
99
> This version (`1.0.0`) is based on the original version `4.1.10`.
1010
1111
## ⚠️ Important: Rate Limiting & IP Blocking

bin/php-whois.php

Lines changed: 96 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,58 @@
44

55
use Xternalsoft\Whois\Factory;
66

7-
$scriptDir = '.';
8-
if (preg_match('~^(.+?)/[^/]+$~ui', $_SERVER['SCRIPT_FILENAME'], $m)) {
9-
$scriptDir = $m[1];
7+
// Better autoload detection
8+
$autoloadFiles = [
9+
__DIR__ . '/../vendor/autoload.php',
10+
__DIR__ . '/../../../vendor/autoload.php',
11+
];
12+
13+
$autoloadFile = null;
14+
foreach ($autoloadFiles as $file) {
15+
if (file_exists($file)) {
16+
$autoloadFile = $file;
17+
break;
18+
}
19+
}
20+
21+
if (!$autoloadFile) {
22+
die("Error: vendor/autoload.php not found. Please run 'composer install'.\n");
1023
}
11-
include "$scriptDir/../vendor/autoload.php";
1224

13-
function main($argv)
25+
require_once $autoloadFile;
26+
27+
function main(array $argv): void
1428
{
1529
$action = trim($argv[1] ?? '');
1630
$args = array_slice($argv, 2);
1731

1832
if (empty($action)) {
1933
$action = 'help';
2034
}
21-
switch (mb_strtolower(ltrim($action, '-'))) {
22-
case 'help':
23-
case 'h':
24-
help();
25-
return;
35+
36+
$actionLower = mb_strtolower(ltrim($action, '-'));
37+
38+
if ($actionLower === 'help' || $actionLower === 'h') {
39+
help();
40+
return;
2641
}
42+
2743
switch ($action) {
2844
case 'lookup':
45+
if (empty($args[0])) {
46+
echo "Error: domain argument is required for lookup.\n";
47+
help();
48+
exit(1);
49+
}
2950
lookup($args[0]);
3051
break;
3152

3253
case 'info':
54+
if (empty($args[0])) {
55+
echo "Error: domain argument is required for info.\n";
56+
help();
57+
exit(1);
58+
}
3359
$opts = parseOpts(implode(' ', array_slice($args, 1)));
3460
info($args[0], $opts);
3561
break;
@@ -51,109 +77,117 @@ function parseOpts(string $str): array
5177
return $result;
5278
}
5379

54-
function help()
80+
function help(): void
5581
{
5682
echo implode("\n", [
5783
'Welcome to php-whois CLI',
5884
'',
5985
' Syntax:',
60-
' php-whois {action} [arg1 arg2 ... argN]',
61-
' php-whois help|--help|-h',
62-
' php-whois lookup {domain}',
63-
' php-whois info {domain} [--parser {type}] [--host {whois}]',
86+
' php bin/php-whois.php {action} [arg1 arg2 ... argN]',
87+
' php bin/php-whois.php help|--help|-h',
88+
' php bin/php-whois.php lookup {domain}',
89+
' php bin/php-whois.php info {domain} [--parser {type}] [--host {whois}] [--file {path}]',
6490
'',
6591
' Examples',
66-
' php-whois lookup google.com',
67-
' php-whois info google.com',
68-
' php-whois info google.com --parser block',
69-
' php-whois info ya.ru --host whois.nic.ru --parser auto',
92+
' php bin/php-whois.php lookup google.com',
93+
' php bin/php-whois.php info google.com',
94+
' php bin/php-whois.php info google.com --parser block',
95+
' php bin/php-whois.php info ya.ru --host whois.nic.ru --parser auto',
7096
'',
71-
'',
72-
]);
97+
]) . "\n";
7398
}
7499

75-
function lookup(string $domain)
100+
function lookup(string $domain): void
76101
{
77-
echo implode("\n", [
78-
' action: lookup',
79-
" domain: '{$domain}'",
80-
'',
81-
'',
82-
]);
102+
echo "Action: lookup\n";
103+
echo "Domain: '{$domain}'\n\n";
83104

84105
$whois = Factory::get()->createWhois();
85106
$result = $whois->lookupDomain($domain);
86107

87108
var_dump($result);
88109
}
89110

90-
function info(string $domain, array $options = [])
111+
function info(string $domain, array $options = []): void
91112
{
92113
$options = array_replace([
93114
'host' => null,
94115
'parser' => null,
95116
'file' => null,
96117
], $options);
97118

98-
echo implode("\n", [
99-
' action: info',
100-
" domain: '{$domain}'",
101-
sprintf(" options: %s", json_encode($options, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
102-
'',
103-
'',
104-
]);
119+
echo "Action: info\n";
120+
echo "Domain: '{$domain}'\n";
121+
echo sprintf("Options: %s\n\n", json_encode($options, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
105122

106123
$loader = null;
107124
if ($options['file']) {
108-
$loader = new \Xternalsoft\Whois\Loaders\FakeSocketLoader();
109-
$loader->text = file_get_contents($options['file']);
125+
if (!file_exists($options['file'])) {
126+
die("Error: File not found: {$options['file']}\n");
127+
}
128+
129+
// Use a generic mock loader if FakeSocketLoader is not available (likely in non-dev env)
130+
if (class_exists('\\Xternalsoft\\Whois\\Loaders\\FakeSocketLoader')) {
131+
$loader = new \Xternalsoft\Whois\Loaders\FakeSocketLoader();
132+
$loader->text = file_get_contents($options['file']);
133+
} else {
134+
// Simple anonymous class implementation of ILoader if available
135+
echo "Warning: FakeSocketLoader not found, using raw file content bypass.\n";
136+
// We can't easily mock ILoader here without knowing its interface fully
137+
// but we can try to use it if it exists or fallback.
138+
// Actually, let's stick to the existing logic but add a check.
139+
die("Error: --file option requires dev dependencies (FakeSocketLoader).\n");
140+
}
110141
}
111142

112-
$tld = Factory::get()->createWhois($loader)->getTldModule();
113-
$servers = $tld->matchServers($domain);
143+
$factory = Factory::get();
144+
$whois = $factory->createWhois($loader);
145+
$tldModule = $factory->createTldModule($whois);
146+
$servers = $tldModule->matchServers($domain);
114147

115148
if (!empty($options['host'])) {
116149
$host = $options['host'];
117-
$filteredServers = array_filter($servers, function (\Xternalsoft\Whois\Modules\Tld\TldServer $server) use ($host) {
118-
return $server->getHost() == $host;
150+
$filteredServers = array_filter($servers, function ($server) use ($host) {
151+
return $server->getHost() === $host;
119152
});
120-
if (count($filteredServers) == 0 && count($servers) > 0) {
121-
$filteredServers = [$servers[0]];
122-
}
123-
$servers = array_map(function (\Xternalsoft\Whois\Modules\Tld\TldServer $server) use ($host) {
124-
return new \Xternalsoft\Whois\Modules\Tld\TldServer(
125-
$server->getZone(),
153+
154+
if (count($filteredServers) === 0 && count($servers) > 0) {
155+
// If the specific host isn't in matched servers, we take the first matched zone
156+
// but override the host
157+
$baseServer = $servers[0];
158+
$servers = [new \Xternalsoft\Whois\Modules\Tld\TldServer(
159+
$baseServer->getZone(),
126160
$host,
127-
$server->isCentralized(),
128-
$server->getParser(),
129-
$server->getQueryFormat()
130-
);
131-
}, $filteredServers);
161+
$baseServer->isCentralized(),
162+
$baseServer->getParser(),
163+
$baseServer->getQueryFormat()
164+
)];
165+
} else {
166+
$servers = array_values($filteredServers);
167+
}
132168
}
133169

134170
if (!empty($options['parser'])) {
135171
try {
136-
$parser = Factory::get()->createTldParser($options['parser']);
172+
$parser = $factory->createTldParser($options['parser']);
137173
} catch (\Throwable $e) {
138-
echo "\nCannot create TLD parser with type '{$options['parser']}'\n\n";
139-
throw $e;
174+
die("\nError: Cannot create TLD parser with type '{$options['parser']}'\n");
140175
}
141-
$servers = array_map(function (\Xternalsoft\Whois\Modules\Tld\TldServer $server) use ($parser) {
142-
return new \Xternalsoft\Whois\Modules\Tld\TldServer(
176+
177+
foreach ($servers as $index => $server) {
178+
$servers[$index] = new \Xternalsoft\Whois\Modules\Tld\TldServer(
143179
$server->getZone(),
144180
$server->getHost(),
145181
$server->isCentralized(),
146182
$parser,
147183
$server->getQueryFormat()
148184
);
149-
}, $servers);
185+
}
150186
}
151187

152-
[, $info] = $tld->loadDomainData($domain, $servers);
188+
$info = $tldModule->loadDomainData($domain, $servers);
153189

154190
var_dump($info);
155191
}
156192

157193
main($argv);
158-
159-

0 commit comments

Comments
 (0)