Применение порта восемьдесят для веб-приложений на PHP
Работа с портом 80 в PHP
Веб-серверы традиционно используют порт 80 для HTTP-трафика. PHP предоставляет несколько способов взаимодействия с этим портом: от встроенного сервера до низкоуровневых сокетов. В этом разделе рассмотрены основные варианты с примерами и типичными проблемами.
Как запустить встроенный сервер PHP на порту 80?
Самый быстрый способ – использовать встроенный сервер PHP. Команда запуска:
php -S 0.0.0.0:80 -t /var/www/htmlPhp 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-соединения.