Position actuelle: Accueil> Derniers articles> Comment utiliser GetServbyName de PHP pour déterminer si un nom de service est valide?

Comment utiliser GetServbyName de PHP pour déterminer si un nom de service est valide?

gitbox 2025-09-12

Dans PHP, getServbyName (string $ service, string $ protocole) peut renvoyer le numéro de port (décimal entier) en fonction du nom du service (tel que HTTP , SSH ) et du protocole ( TCP ou UDP ). Si le nom du service ne peut être trouvé ou si une erreur se produit, la fonction renvoie false . Par conséquent, nous pouvons l'utiliser pour déterminer si un nom de service existe dans la base de données System Service (tel que / etc / services sous Linux, fichiers de services pour Windows) - Remarque: Ceci est de vérifier si le nom est mappé au port, plutôt que pour vérifier si le service est actuellement connecté ou disponible.

L'exemple suivant montre l'utilisation commune, les fonctions d'encapsulation, les considérations et les méthodes de détection supplémentaires pour la disponibilité réelle (si vous devez confirmer que le service est vraiment connecté).


Utilisation de base

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$service</span></span><span> = </span><span><span class="hljs-string">'http'</span></span><span>;
</span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-string">'tcp'</span></span><span>;

</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-title function_ invoke__">getservbyname</span></span><span>(</span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-variable">$protocol</span></span><span>);

</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$port</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Nom de service '<span class="hljs-subst">{$service}</span></span></span><span>'(protocole </span><span><span class="hljs-subst">{$protocol}</span></span><span>)N&#39;existe pas dans la base de données de services natives。\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Servir '<span class="hljs-subst">{$service}</span></span></span><span>'(</span><span><span class="hljs-subst">{$protocol}</span></span><span>)Carte au port:</span><span><span class="hljs-subst">{$port}</span></span><span>\n";
}
</span></span>

Fonction d'encapsulation de jugement recommandé

Cette fonction fera un jugement plus robuste: vérifiez la valeur de retour GetServbyName et assurez-vous que le numéro de port se situe dans la plage juridique (1–65535):

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
<span class="hljs-comment">/**
 * 判断Nom de service称是否有效(在Cette machineServir数据库中有对应端口)
 *
 * </span></span><span><span class="hljs-doctag">@param</span></span><span> string $service Nom de service称,Par exemple 'http'、'ssh'
 * </span><span><span class="hljs-doctag">@param</span></span><span> string $protocol protocole 'tcp' ou 'udp'
 * </span><span><span class="hljs-doctag">@return</span></span><span> bool retour true Cela signifie valable(Trouvez le port légal),false 表示无效ou出错
 */
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">is_service_name_valid</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-string">'tcp'</span></span><span>): </span><span><span class="hljs-title">bool</span></span><span>
{
    </span><span><span class="hljs-comment">// Paramètres normalisés</span></span><span>
    </span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-title function_ invoke__">strtolower</span></span><span>(</span><span><span class="hljs-variable">$protocol</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">in_array</span></span><span>(</span><span><span class="hljs-variable">$protocol</span></span><span>, [</span><span><span class="hljs-string">'tcp'</span></span><span>, </span><span><span class="hljs-string">'udp'</span></span><span>], </span><span><span class="hljs-literal">true</span></span><span>)) {
        </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
    }

    </span><span><span class="hljs-variable">$port</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">getservbyname</span></span><span>(</span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-variable">$protocol</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$port</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
        </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
    }

    </span><span><span class="hljs-comment">// Assurez-vous que le port est dans la portée légale</span></span><span>
    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">is_int</span></span><span>(</span><span><span class="hljs-variable">$port</span></span><span>) &amp;&amp; </span><span><span class="hljs-variable">$port</span></span><span> &gt;= </span><span><span class="hljs-number">1</span></span><span> &amp;&amp; </span><span><span class="hljs-variable">$port</span></span><span> &lt;= </span><span><span class="hljs-number">65535</span></span><span>;
}

</span><span><span class="hljs-comment">// Exemple</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_service_name_valid</span></span><span>(</span><span><span class="hljs-string">'http'</span></span><span>, </span><span><span class="hljs-string">'tcp'</span></span><span>));  </span><span><span class="hljs-comment">// en général true</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_service_name_valid</span></span><span>(</span><span><span class="hljs-string">'nosuchservice'</span></span><span>, </span><span><span class="hljs-string">'tcp'</span></span><span>)); </span><span><span class="hljs-comment">// false</span></span><span>
</span></span>

Dépendances et limitations de la plate-forme (importantes)

  • getServbyName interroge la base de données de services du système d'exploitation (tel que / etc / services ). Différents systèmes, différents environnements d'installation et différentes distributions peuvent contenir différentes entrées. Par exemple, certains services personnalisés existent sur un hôte et non sur un autre.

  • Cette fonction vous indique seulement si le nom du service a une carte de port - cela ne signifie pas que le service de ce port est actuellement en cours d'exécution ou connecté . Si vous devez vérifier la "disponibilité du service", vous devez également effectuer des tests de connexion réseau (tels que FSOCOpen , Stream_Socket_Client ou Socket_Create / Socket_Connect ).

  • Le protocole doit être «TCP» ou «UDP» (cas insensible). D'autres valeurs seront considérées comme invalides.

Si vous souhaitez également confirmer si le service est connecté (facultatif)

La détermination de l'existence d'un nom de service n'est que la première étape. Si vous souhaitez vérifier si l'hôte distant (ou l'hôte local) accepte les connexions sur ce port de service, vous pouvez d'abord utiliser getServbyName pour obtenir le port, puis essayer d'établir la connexion.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
<span class="hljs-comment">/**
 * Utiliser d&#39;abord getservbyname 判断Nom de service,Essayez de vous connecter au port de l&#39;hôte cible pour confirmer l&#39;accessibilité
 *
 * </span></span><span><span class="hljs-doctag">@param</span></span><span> string $host Hôte cible(IP ou Nom d&#39;hôte)
 * </span><span><span class="hljs-doctag">@param</span></span><span> string $service Nom de service称
 * </span><span><span class="hljs-doctag">@param</span></span><span> string $protocol 'tcp' ou 'udp'(Uniquement implémenté ici tcp Détection de connexion)
 * </span><span><span class="hljs-doctag">@param</span></span><span> float $timeout Deuxième(Par exemple 2.0)
 * </span><span><span class="hljs-doctag">@return</span></span><span> bool true Indique que le port est trouvé et peut être établi TCP connecter,false sinon
 */
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">is_service_reachable</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-string">'tcp'</span></span><span>, </span><span><span class="hljs-keyword">float</span></span><span> </span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">2.0</span></span><span>): </span><span><span class="hljs-title">bool</span></span><span>
{
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">strtolower</span></span><span>(</span><span><span class="hljs-variable">$protocol</span></span><span>) !== </span><span><span class="hljs-string">'tcp'</span></span><span>) {
        </span><span><span class="hljs-comment">// simplifier:Faites seulement ici TCP Détection de connectivité;UDP Détection plus complexe(无connecter/Aucune confirmation)</span></span><span>
        </span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">'is_service_reachable Actuellement soutenu uniquement tcp Test'</span></span><span>);
    }

    </span><span><span class="hljs-variable">$port</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">getservbyname</span></span><span>(</span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-variable">$protocol</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$port</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span> || !</span><span><span class="hljs-title function_ invoke__">is_int</span></span><span>(</span><span><span class="hljs-variable">$port</span></span><span>) || </span><span><span class="hljs-variable">$port</span></span><span> &lt; </span><span><span class="hljs-number">1</span></span><span> || </span><span><span class="hljs-variable">$port</span></span><span> &gt; </span><span><span class="hljs-number">65535</span></span><span>) {
        </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
    }

    </span><span><span class="hljs-variable">$errno</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>;
    </span><span><span class="hljs-variable">$errstr</span></span><span> = </span><span><span class="hljs-string">''</span></span><span>;
    </span><span><span class="hljs-variable">$fp</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">fsockopen</span></span><span>(</span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$fp</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
        </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
    }

    </span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$fp</span></span><span>);
    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">true</span></span><span>;
}

</span><span><span class="hljs-comment">// Exemple</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_service_reachable</span></span><span>(</span><span><span class="hljs-string">'127.0.0.1'</span></span><span>, </span><span><span class="hljs-string">'ssh'</span></span><span>, </span><span><span class="hljs-string">'tcp'</span></span><span>, </span><span><span class="hljs-number">1.5</span></span><span>)); </span><span><span class="hljs-comment">// Cette machine ssh Servir是否可达</span></span><span>
</span></span>

Remarque: le jugement de «réactionnabilité» d'UDP n'est pas une connexion simple: il est généralement nécessaire d'envoyer un paquet de sonde et d'attendre une réponse, ou d'utiliser une API à douille plus complexe (et peut être rejetée par le pare-feu). Si la détection UDP est effectivement requise, implémentez la logique de détection de la couche d'application ou utilisez des outils spécialisés.

Cas d'utilisation courants et suggestions

  1. Vérification de la configuration : Lorsque l'utilisateur entre le nom du service (tel que SMTP , IMAP ) dans l'interface de configuration, utilisez d'abord getServbyName pour vérifier si le nom est reconnu par le système. S'il n'est pas reconnu, l'utilisateur peut être invité à utiliser le numéro de port ou à sélectionner un autre nom de service.

  2. Compatibilité : ne comptez pas sur la base de données de services du système - maintenez une table de mappage dans l'application (telle que 'http' => 80 ) en tant que repli lorsque la cohérence multiplateforme est requise.

  3. Autorisations et sécurité : lorsque vous essayez de connecter les ports pour la détection d'accessibilité, faites attention aux politiques du réseau, aux pare-feu et aux limites de taux. Ne détectez pas fréquemment un grand nombre d'hôtes en peu de temps pour éviter les abus ou déclencher des alarmes de sécurité.

  4. Gestion des erreurs : getServbyName peut renvoyer false , veuillez le gérer explicitement dans le code au lieu d'utiliser directement la valeur de retour.

résumé

  • Utilisez getServbyName ($ Service, $ Protocol) pour déterminer si le nom du service a une carte de port dans la base de données du service système local (renvoie le numéro de port ou false ).

  • Il est préférable de vérifier le type de valeur de retour lors de la validité de la validité et de s'assurer que le port se situe dans la plage de 1 à 65535.

  • Cette méthode ne signifie pas que le service est disponible ; Si la disponibilité est requise, une détection supplémentaire au niveau de la connexion réseau (telle que fsocckopen , etc.) est requise.

  • Remarque Les différences de plate-forme: les entrées de base de données de service de différents systèmes sont différentes. Si vous avez des exigences multiplateformes, veuillez vous préparer à la cartographie de secours ou demander à l'utilisateur de fournir le numéro de port.