Last active
          December 21, 2024 17:29 
        
      - 
      
- 
        Save oneluiz/280854f5120320c76aef5bcd2cf7d6f1 to your computer and use it in GitHub Desktop. 
    PHP code to get WHOIS information of a domain
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | <?php | |
| /** | |
| * Servicio para realizar consultas WHOIS de dominios. | |
| * | |
| * Esta clase implementa el patrón Singleton para garantizar que solo exista | |
| * una instancia del servicio, evitando consultas innecesarias y reduciendo el | |
| * consumo de recursos. | |
| * | |
| * @author Luis Cortés | |
| */ | |
| class WhoisService { | |
| private static ?WhoisService $instance = null; | |
| private array $whoisServers; | |
| /** | |
| * Constructor privado para inicializar servidores WHOIS. | |
| * Se utiliza para cargar una lista de servidores para diferentes extensiones de dominio. | |
| */ | |
| private function __construct() { | |
| $this->whoisServers = [ | |
| '.com' => ['whois.crsnic.net', 'No match for'], | |
| '.net' => ['whois.crsnic.net', 'No match for'], | |
| '.bo' => ['whois.nic.bo', 'solo acepta consultas con dominios .bo'], | |
| '.mx' => ['whois.nic.mx', 'No_Se_Encontro_El_Objeto'], | |
| '.pe' => ['whois.nic.pe', 'No Object Found'], | |
| '.co' => ['whois.nic.co', 'Not found'], | |
| '.es' => ['whois.nic.es', 'Not found'], | |
| '.uk' => ['whois.nic.uk', 'No match for'], | |
| '.org' => ['whois.pir.org', 'NOT FOUND'], | |
| '.info'=> ['whois.afilias.net', 'NOT FOUND'], | |
| '.io' => ['whois.nic.io', 'NOT FOUND'], | |
| '.ai' => ['whois.ai', 'No Object Found'], | |
| '.us' => ['whois.nic.us', 'Not found'], | |
| '.ca' => ['whois.cira.ca', 'Domain status: available'], | |
| '.fr' => ['whois.nic.fr', 'No entries found'], | |
| '.it' => ['whois.nic.it', 'AVAILABLE'], | |
| '.au' => ['whois.auda.org.au', 'No Data Found'] | |
| ]; | |
| } | |
| /** | |
| * Devuelve la instancia única del servicio WHOIS (Singleton). | |
| * | |
| * Se utiliza el patrón Singleton para evitar instancias duplicadas, | |
| * asegurando que haya una única fuente de verdad para las consultas WHOIS. | |
| * | |
| * @return WhoisService | |
| */ | |
| public static function getInstance(): WhoisService { | |
| return self::$instance ??= new WhoisService(); | |
| } | |
| /** | |
| * Realiza una consulta WHOIS a un servidor especificado. | |
| * | |
| * @param string $domain Nombre de dominio sin extensión. | |
| * @param string $extension Extensión de dominio (e.g. .com, .net). | |
| * @return string Mensaje HTML con el resultado de la consulta. | |
| * @throws InvalidArgumentException Si la extensión del dominio no está soportada. | |
| */ | |
| public function performWhoisQuery(string $domain, string $extension): string { | |
| $serverInfo = $this->whoisServers[$extension] ?? null; | |
| if (!$serverInfo) { | |
| throw new InvalidArgumentException("Unsupported domain extension: $extension"); | |
| } | |
| [$whoisServer, $notFoundMsg] = $serverInfo; | |
| $response = $this->queryWhoisServer($whoisServer, $domain . $extension); | |
| return $this->generateResponse($domain . $extension, $response, $notFoundMsg); | |
| } | |
| /** | |
| * Realiza la consulta al servidor WHOIS. | |
| * | |
| * Este método establece una conexión socket al servidor WHOIS especificado | |
| * y realiza la consulta de disponibilidad del dominio. Devuelve el resultado | |
| * completo de la consulta. | |
| * | |
| * @param string $whoisServer Servidor WHOIS a consultar. | |
| * @param string $domain Nombre de dominio completo (con extensión). | |
| * @return array Estado de la consulta y datos recibidos. | |
| */ | |
| private function queryWhoisServer(string $whoisServer, string $domain): array { | |
| $response = ['status' => false, 'data' => '']; | |
| try { | |
| $sock = @fsockopen($whoisServer, 43, $errno, $errstr, 10); | |
| if ($sock) { | |
| fwrite($sock, $domain . "\r\n"); | |
| while (!feof($sock)) { | |
| $response['data'] .= fgets($sock, 128); | |
| } | |
| fclose($sock); | |
| $response['status'] = true; | |
| } | |
| } catch (Throwable $e) { | |
| error_log("WHOIS error: " . $e->getMessage()); | |
| } | |
| return $response; | |
| } | |
| /** | |
| * Genera el mensaje de respuesta basado en el resultado de la consulta. | |
| * | |
| * Determina si el dominio está disponible comparando el resultado de la | |
| * consulta con el mensaje que indica que no se encontró el dominio. | |
| * | |
| * @param string $domain Nombre de dominio consultado. | |
| * @param array $result Resultado de la consulta (estado y datos). | |
| * @param string $notFoundMsg Mensaje que indica que el dominio está disponible. | |
| * @return string HTML con la respuesta de dominio disponible o no. | |
| */ | |
| private function generateResponse(string $domain, array $result, string $notFoundMsg): string { | |
| $available = $result['status'] && str_contains($result['data'], $notFoundMsg); | |
| $whoisData = htmlspecialchars($result['data'] ?? ''); | |
| return $available | |
| ? $this->successTemplate($domain) | |
| : $this->errorTemplate($domain, $whoisData); | |
| } | |
| /** | |
| * Plantilla de mensaje para dominios disponibles. | |
| * | |
| * @param string $domain | |
| * @return string HTML con mensaje de dominio disponible. | |
| */ | |
| private function successTemplate(string $domain): string { | |
| return '<div class="alert alert-success alert-dismissible" role="alert">' | |
| . '<button type="button" class="close" data-dismiss="alert">×</button>' | |
| . '<span>Yes! Your domain <strong>' . htmlspecialchars($domain) . '</strong> is available. Buy it now!</span>' | |
| . '<button class="btn btn-success ml-3" type="button">Buy this domain</button></div>'; | |
| } | |
| /** | |
| * Plantilla de mensaje para dominios no disponibles. | |
| * | |
| * @param string $domain | |
| * @param string $whoisData | |
| * @return string HTML con mensaje de dominio no disponible. | |
| */ | |
| private function errorTemplate(string $domain, string $whoisData): string { | |
| return '<div class="alert alert-light alert-dismissible" role="alert">' | |
| . '<button type="button" class="close" data-dismiss="alert">×</button>' | |
| . '<span>Sorry, <strong>' . htmlspecialchars($domain) . '</strong> is taken.</span>' | |
| . '<a class="btn btn-danger ml-3" data-toggle="collapse" href="#collapseDetails">View details</a>' | |
| . '<div class="collapse" id="collapseDetails"><pre>' . $whoisData . '</pre></div></div>'; | |
| } | |
| } | |
| // Uso del servicio para manejar la entrada de usuario y ejecutar consultas WHOIS. | |
| try { | |
| $domainName = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING) ?? ''; | |
| $domainExt = filter_input(INPUT_POST, 'Ext', FILTER_SANITIZE_STRING) ?? ''; | |
| if ($domainName && $domainExt) { | |
| $cleanDomain = preg_replace('/^(www\\.|http:\/\/|\/)/', '', $domainName); | |
| echo WhoisService::getInstance()->performWhoisQuery($cleanDomain, $domainExt); | |
| } | |
| } catch (Exception $e) { | |
| echo '<div class="alert alert-danger">Error: ' . htmlspecialchars($e->getMessage()) . '</div>'; | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment