W3docs

Функция PHP getservbyname(): всё, что нужно знать

Функция PHP getservbyname() позволяет получить номер порта по имени службы. Узнайте синтаксис, примеры использования и типичные ошибки.

Сетевые службы идентифицируются общеизвестными именами, такими как http, ftp или smtp, однако операционная система маршрутизирует трафик по номеру порта (80, 21, 25 и т. д.). Функция PHP getservbyname() выполняет поиск этого номера порта, обращаясь к той же базе данных служб, которую использует остальная часть системы. На этой странице описаны синтаксис, принцип работы базы данных, типичные сценарии использования и возможные проблемы.

Синтаксис

getservbyname(string $service, string $protocol): int|false

Функция принимает два обязательных параметра:

  • $service — имя интернет-службы, например "http", "ssh" или "smtp".
  • $protocol — транспортный протокол: "tcp" или "udp". Вопреки утверждениям многих устаревших документаций, этот аргумент не является необязательным — его необходимо передавать явно.

В случае успеха функция возвращает номер порта как целое число (integer), а если пара служба/протокол не найдена — false. Поскольку false и допустимый номер порта могут вести себя схожим образом в контексте «ложных» значений, при проверке на ошибку всегда используйте строгий оператор ===.

Откуда берутся данные

getservbyname() не устанавливает никаких соединений и не делает предположений. Функция читает локальную таблицу поиска:

  • На Linux и macOS это файл /etc/services.
  • На Windows — %SystemRoot%\system32\drivers\etc\services.

Если службы нет в этом файле, поиск завершится неудачей, даже если служба «очевидно» существует. Результат, таким образом, зависит от конкретной машины, на которой выполняется скрипт, а не является универсальной константой.

Базовый пример

php— editable, runs on the server

Проверка === false важна: она чётко отделяет реальный сбой от допустимого результата, например порта 0 (который был бы «ложным» при нестрогом сравнении ==).

Поиск нескольких служб

На практике часто требуется разрешить сразу целый набор имён — например, для формирования отчёта о брандмауэре или проверки конфигурации:

<?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 против UDP

Одно и то же имя службы может разрешаться в разные записи в зависимости от протокола, а некоторые службы существуют только для одного из них. Всегда передавайте тот протокол, который вам действительно нужен:

<?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 service

Когда это использовать?

  • Динамическое построение сетевых клиентов. Разрешите имя службы в номер порта перед открытием сокета с помощью fsockopen() или pfsockopen(), чтобы в коде было читаемое "smtp" вместо магического числа 25.
  • Проверка конфигурации. Убедитесь, что имя службы из файла конфигурации действительно известно хосту, прежде чем использовать его.
  • Отчёты и инструментарий. Преобразуйте понятные человеку имена служб в номера портов для журналов, панелей мониторинга или правил брандмауэра.

Связанные функции

  • getservbyport() — обратная операция: по номеру порта и протоколу возвращает имя службы.
  • getprotobyname() — поиск номера протокола (например, tcp6) по его имени.

Типичные ошибки

  • Оба аргумента обязательны. Пропуск $protocol вызовет ошибку; неявного значения по умолчанию нет.
  • Только строгое сравнение. Используйте === false для обнаружения ошибки, чтобы не спутать её с портом 0 или граничными случаями числовых строк.
  • Результат зависит от хоста. Ответ берётся из локальной базы данных служб; имя, неизвестное одной машине, может успешно разрешиться на другой.
  • Функция работает офлайн. Никакого DNS, никакой сети — только локальный поиск по таблице. Это быстро и безопасно вызывать часто.

Резюме

getservbyname() отображает имя службы и протокол на номер порта, используя базу данных служб операционной системы, и возвращает целое число — номер порта, или false, если пара не найдена. Используйте её в паре с getservbyport() для обратного поиска и с fsockopen(), когда нужно превратить этот порт в реальное соединение.

Практика

Практика
Какова цель функции getservbyname() в PHP?
Какова цель функции getservbyname() в PHP?
Was this page helpful?