Fonction PHP getservbyname() : tout ce que vous devez savoir
En tant que développeur PHP, vous pouvez avoir besoin d'obtenir le numéro de port associé à un nom de service. La fonction PHP getservbyname() répond à ce besoin.
Les services réseau sont identifiés par des noms bien connus tels que http, ftp ou smtp, mais le système d'exploitation achemine en réalité le trafic par numéro de port (80, 21, 25, etc.). La fonction getservbyname() de PHP recherche ce numéro de port pour vous, en lisant la même base de données de services que le reste du système. Cette page explique la syntaxe, ce qu'est cette base de données, les cas d'usage courants et les pièges à éviter.
Syntaxe
getservbyname(string $service, string $protocol): int|falseLa fonction prend deux paramètres obligatoires :
$service— le nom du service Internet, par exemple"http","ssh"ou"smtp".$protocol— le protocole de transport, soit"tcp"soit"udp". Contrairement à ce que suggèrent beaucoup d'anciennes documentations, cet argument n'est pas optionnel ; vous devez le passer.
Elle retourne le numéro de port sous forme d'entier en cas de succès, ou false si la paire service/protocole n'est pas trouvée. Étant donné que false et un port valide peuvent tous deux sembler « faussement falsy », utilisez toujours l'opérateur strict === pour vérifier un échec.
D'où proviennent les données
getservbyname() ne se connecte à rien et ne fait aucune supposition. Elle lit une table de correspondance locale :
- Sur Linux et macOS, il s'agit du fichier
/etc/services. - Sur Windows, il s'agit de
%SystemRoot%\system32\drivers\etc\services.
Si un service est absent de ce fichier, la recherche échoue même si le service « existe de toute évidence ». Le résultat dépend donc de la machine qui exécute le script, et non d'une constante universelle.
Un exemple de base
La vérification === false est importante : elle distingue clairement un vrai échec d'un résultat légitime comme le port 0 (qui serait falsy avec une comparaison lâche ==).
Rechercher plusieurs services
En pratique, vous résolvez souvent un lot de noms à la fois — par exemple pour générer un rapport de pare-feu ou valider une configuration :
<?php
$services = ["http", "https", "ftp", "smtp", "ssh"];
foreach ($services as $name) {
$port = getservbyname($name, "tcp");
echo $port === false
? "{$name}: not found\n"
: "{$name}: {$port}\n";
}
/*
Output:
http: 80
https: 443
ftp: 21
smtp: 25
ssh: 22
*/TCP vs UDP
Le même nom de service peut correspondre à des entrées différentes selon le protocole, et certains services n'existent que pour l'un d'eux. Passez toujours le protocole qui vous concerne réellement :
<?php
var_dump(getservbyname("domain", "tcp")); // int(53) — DNS over TCP
var_dump(getservbyname("domain", "udp")); // int(53) — DNS over UDP
var_dump(getservbyname("ntp", "udp")); // int(123)
var_dump(getservbyname("madeup", "tcp")); // bool(false) — unknown serviceQuand utiliser cette fonction ?
- Construire des clients réseau dynamiquement. Résolvez un nom de service en port avant d'ouvrir un socket avec
fsockopen()oupfsockopen(), afin que votre code lise"smtp"plutôt qu'un nombre magique25. - Valider une configuration. Vérifiez qu'un nom de service provenant d'un fichier de configuration est réellement connu de l'hôte avant de l'utiliser.
- Rapports et outillage. Traduisez des noms de services lisibles par l'humain en numéros de ports pour des journaux, des tableaux de bord ou des règles de pare-feu.
Fonctions associées
getservbyport()— la fonction inverse : à partir d'un numéro de port et d'un protocole, elle retourne le nom du service.getprotobyname()— recherche un numéro de protocole (ex.tcp→6) à partir de son nom.
Pièges courants
- Les deux arguments sont obligatoires. Omettre
$protocolprovoque une erreur ; il n'y a pas de valeur par défaut implicite. - Comparaison stricte uniquement. Utilisez
=== falsepour détecter un échec afin de ne pas confondre le port0ou un cas limite de chaîne numérique. - Résultats dépendants de l'hôte. La réponse provient de la base de données de services locale ; un nom inconnu d'une machine peut se résoudre sur une autre.
- Hors ligne. Pas de DNS, pas de réseau — uniquement une recherche dans une table locale, donc rapide et sans risque à appeler fréquemment.
Résumé
getservbyname() associe un nom de service et un protocole à un numéro de port en utilisant la base de données de services du système d'exploitation, en retournant un port entier ou false si la paire est inconnue. Combinez-la avec getservbyport() pour la direction inverse et avec fsockopen() lorsque vous devez transformer ce port en connexion réelle.