Применение порта восемьдесят для веб-приложений на PHP

Раздел: Сетевое программирование -> Сетевое программирование

Работа с портом 80 в PHP

Веб-серверы традиционно используют порт 80 для HTTP-трафика. PHP предоставляет несколько способов взаимодействия с этим портом: от встроенного сервера до низкоуровневых сокетов. В этом разделе рассмотрены основные варианты с примерами и типичными проблемами.

Как запустить встроенный сервер PHP на порту 80?

Самый быстрый способ – использовать встроенный сервер PHP. Команда запуска:

php -S 0.0.0.0:80 -t /var/www/html

Php socket connect (подключение через сокеты в php)

Пояснение: -S включает сервер, 0.0.0.0:80 привязывает к порту 80 на всех интерфейсах, -t задаёт корневую директорию для документов.

Возможные проблемы:

  • Permission denied: порты ниже 1024 требуют прав суперпользователя. Решение: запускать через sudo php -S ... или использовать порт выше 1024.
  • Address already in use: порт уже занят другим процессом. Проверить командой sudo netstat -tlnp | grep :80 и остановить конфликтующий сервер.
  • Ограничение производительности: встроенный сервер однопоточный, подходит для разработки, не для продакшена.

Как проверить, занят ли порт 80, из PHP?

Можно использовать fsockopen или stream_socket_client для попытки подключения. Если подключение удаётся – порт открыт.

$fp = @fsockopen('127.0.0.1', 80, $errno, $errstr, 5);
if ($fp) {
    echo 'Порт 80 открыт';
    fclose($fp);
} else {
    echo 'Порт 80 закрыт или не отвечает: ' . $errstr;
}

Php port 80 (порт 80 в php)

Пояснение: @ подавляет предупреждения, 5 – таймаут подключения в секундах. $errno и $errstr содержат информацию об ошибке.

Ошибки:

  • Connection refused: порт не слушает ни один процесс.
  • Timeout: слишком большое время ожидания или брандмауэр блокирует соединение.

Как создать простой TCP-сервер на порту 80 в PHP?

PHP позволяет открыть сокет для прослушивания с помощью stream_socket_server. Это основа для кастомных серверов.

$server = stream_socket_server('tcp://0.0.0.0:80', $errno, $errstr);
if (!$server) {
    die("Не удалось создать сервер: $errstr ($errno)");
}
echo "Сервер запущен на порту 80\n";
while ($conn = stream_socket_accept($server, 30)) {
    fwrite($conn, "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!");
    fclose($conn);
}

Пояснение: stream_socket_server создаёт серверный сокет. stream_socket_accept ждёт входящее соединение. В примере отправляется минимальный HTTP-ответ.

Типичные проблемы:

  • Блокировка: цикл ожидает одно соединение за раз. Для параллельной обработки нужно использовать stream_select или pcntl_fork.
  • Права доступа: снова требуется root для порта 80.
  • Необработанные ошибки: при разрыве соединения fwrite может выдать предупреждение.

Как узнать, какой процесс использует порт 80, из PHP?

Можно выполнить системную команду netstat или ss через exec и разобрать вывод.

exec('ss -tlnp | grep :80', $output, $return);
if ($return === 0 && !empty($output)) {
    echo implode("\n", $output);
} else {
    echo 'Порт 80 не занят';
}

Пояснение: ss -tlnp показывает слушающие TCP-сокеты, grep :80 фильтрует порт. Вывод может содержать PID и имя программы.

Проблемы:

  • Права: без root команда может не показывать процессы других пользователей. Рекомендуется sudo ss.
  • Зависимость от ОС: на разных системах утилиты могут называться иначе (netstat вместо ss).

Расширенные примеры работы с портом 80 в PHP

Запуск встроенного сервера с роутером и несколькими рабочими процессами

Цель: продемонстрировать более гибкий запуск встроенного сервера с PHP-роутером и опцией -n для многопоточности (только в некоторых версиях).

Пример
// Создаём файл router.php
<?php
$uri = $_SERVER['REQUEST_URI'];
if ($uri === '/') {
    echo 'Главная страница';
} elseif ($uri === '/test') {
    echo 'Тестовая страница';
} else {
    http_response_code(404);
    echo '404 Not Found';
}
?>
Пример
# Запуск с роутером и 4 рабочими процессами (если поддерживается)
php -S 0.0.0.0:80 -t /var/www/html router.php -n 4

Результат: при запросе http://localhost/test сервер выведет «Тестовая страница». Ключ -n доступен в PHP 7.4+ и позволяет запускать несколько воркеров для обработки запросов.

Ошибка: опция -n может отсутствовать в ранних версиях. Вместо неё используют внешние инструменты вроде Supervisor.

Проверка порта 80 с повторными попытками и таймаутами

Цель: реализовать надёжную проверку доступности порта с учётом временных задержек.

Пример
function checkPort80($host = '127.0.0.1', $port = 80, $timeout = 3, $attempts = 2) {
    for ($i = 1; $i <= $attempts; $i++) {
        $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
        if ($fp) {
            fclose($fp);
            return true;
        }
        usleep(500000); // 0.5 сек перед повторной попыткой
    }
    return false;
}

$status = checkPort80();
echo $status ? 'Порт 80 доступен' : 'Порт 80 недоступен';
Порт 80 доступен

Пояснение: функция делает до $attempts попыток с интервалом 0.5 сек. Это помогает отсечь временные отказы.

TCP-сервер с обработкой нескольких клиентов через stream_select

Цель: создать неблокирующий сервер, который может обслуживать несколько соединений без fork.

Пример
$server = stream_socket_server('tcp://0.0.0.0:80', $errno, $errstr);
stream_set_blocking($server, false);
$clients = [];
while (true) {
    $read = array_merge([$server], $clients);
    $write = null;
    $except = null;
    if (stream_select($read, $write, $except, 0, 200000) > 0) {
        if (in_array($server, $read)) {
            $client = @stream_socket_accept($server, 0);
            if ($client) {
                stream_set_blocking($client, false);
                $clients[] = $client;
            }
        }
        foreach ($read as $client) {
            if ($client === $server) continue;
            $data = @fread($client, 8192);
            if ($data === false || $data === '') {
                fclose($client);
                $clients = array_filter($clients, fn($c) => $c !== $client);
            } else {
                fwrite($client, "HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nHello!");
                fclose($client);
                $clients = array_filter($clients, fn($c) => $c !== $client);
            }
        }
    }
    // Дополнительная логика
}

Результат: сервер может обрабатывать несколько клиентов параллельно без блокировки. stream_select возвращает сокеты, готовые к чтению.

Ошибки: если флаг stream_set_blocking(false) не установлен, fread может блокировать. Также возможны утечки памяти при неправильной очистке массива $clients.

Использование curl для проверки удалённого порта 80 из PHP

Цель: проверить, доступен ли удалённый веб-сервер на порту 80 с помощью curl.

Пример
function curlCheckPort80($host = 'example.com', $timeout = 5) {
    $ch = curl_init("http://$host");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $timeout,
        CURLOPT_CONNECTTIMEOUT => $timeout,
        CURLOPT_NOBODY => true, // не загружаем тело
    ]);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $httpCode > 0 ? $httpCode : false;
}

$code = curlCheckPort80();
echo $code ? "Сервер ответил с кодом $code" : 'Сервер недоступен';
Сервер ответил с кодом 200

Пояснение: этот метод подходит для проверки именно HTTP-сервера на порту 80, в отличие от чистого TCP-соединения.

Порт 80 в PHP - comments

En
Php port 80 (php)