W3docs

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

Узнайте, как PHP-функция getprotobyname() возвращает номер протокола по его имени, с примерами и советами по обработке ошибок.

При работе с низкоуровневыми сетевыми возможностями в PHP иногда известно имя протокола, например tcp или udp, а нужен его числовой номер — значение, присвоенное этому протоколу организацией IANA и используемое в заголовках IP-пакетов. Функция getprotobyname() выполняет именно такой поиск. На этой странице рассматриваются её синтаксис, возвращаемое значение, распространённые номера протоколов, обработка ошибок и связь с другими функциями поиска протоколов и служб в PHP.

Что такое функция getprotobyname()?

getprotobyname() — это встроенная функция PHP, которая преобразует имя протокола в соответствующий номер. Она читает системную базу данных протоколов — как правило, /etc/protocols в Unix-подобных системах и %SystemRoot%\System32\drivers\etc\protocol в Windows, — поэтому понимает имена, перечисленные там (например, ip, icmp, tcp, udp, ipv6).

Это обратная функция для getprotobynumber(), которая преобразует номер обратно в имя. Числовой номер протокола обычно нужен при открытии сырого сокета с помощью socket_create() и аналогичных низкоуровневых API, где протокол должен быть указан численно.

Синтаксис

getprotobyname(string $protocol): int|false

Функция принимает один параметр:

  • $protocol — имя протокола для поиска. Поиск нечувствителен к регистру, поэтому "TCP" и "tcp" дают одинаковый результат.

Функция возвращает целое число, представляющее номер протокола, или false, если имя протокола не найдено в системной базе данных.

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

Вот как получить номер протокола tcp и обработать случай, когда поиск не дал результата:

php— editable, runs on the server

Для "tcp" выводится:

The protocol number for protocol name tcp is 6

Обратите внимание на строгое сравнение === false. Поскольку наименьший допустимый номер протокола равен 0 (протокол ip), нестрогая проверка вида if (!$protocol_number) ошибочно расценит успешный поиск ip как неудачу. Всегда сравнивайте с false с помощью ===.

Распространённые номера протоколов

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

Имя протоколаНомерЗначение
ip0Internet Protocol
icmp1Internet Control Message Protocol
tcp6Transmission Control Protocol
udp17User Datagram Protocol
ipv641Internet Protocol v6

Поиск нескольких протоколов

Можно перебрать список имён и вывести каждый результат, корректно обрабатывая неизвестные имена:

<?php

$protocols = ["tcp", "udp", "icmp", "bogus"];

foreach ($protocols as $name) {
    $number = getprotobyname($name);

    if ($number === false) {
        echo "$name: not found\n";
    } else {
        echo "$name => $number\n";
    }
}

Вывод:

tcp => 6
udp => 17
icmp => 1
bogus: not found

Когда это используется?

В повседневной веб-разработке номера протоколов редко нужны — fopen(), cURL и потоковые обёртки принимают URL, а не числа. К getprotobyname() обращаются, когда требуется опуститься на уровень ниже:

  • Создание сырых сокетов. socket_create(AF_INET, SOCK_RAW, getprotobyname("icmp")) передаёт номер протокола в сокет. Жёстко заданное 1 работает, но getprotobyname("icmp") выражает намерение явно и остаётся корректным, если база данных отличается.
  • Формирование или разбор IP-пакетов, где поле протокола является числовым.
  • Сетевые утилиты и диагностика, которые выводят и имя, и номер протокола.

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

  • getprotobynumber() — обратный поиск: по номеру возвращает имя.
  • getservbyname() — преобразует имя службы (например, http) и протокол в номер порта.
  • getservbyport() — обратная функция: по номеру порта возвращает имя службы.
  • fsockopen() — открывает сетевое соединение по хосту и порту.

Заключение

getprotobyname() преобразует имя протокола в числовой номер, определённый в системной базе данных, и возвращает false, если имя не найдено. Не забывайте проверять результат строгим сравнением === false, чтобы допустимое значение 0 для протокола ip не было ошибочно принято за сбой; используйте эту функцию всякий раз, когда низкоуровневый сетевой API ожидает числовой номер протокола, а не его имя.

Практика

Практика
Какова цель функции getprotobyname в PHP, согласно информации на https://www.w3docs.com/learn-php/getprotobyname.html?
Какова цель функции getprotobyname в PHP, согласно информации на https://www.w3docs.com/learn-php/getprotobyname.html?
Was this page helpful?