Как запустить PHP на веб-сервере: связка PHP и Apache

Как запустить PHP на веб-сервере: связка PHP и Apache Полезное

Веб-сервер для PHP — это программа, которая принимает HTTP-запрос по сети, передает его интерпретатору PHP и отдает браузеру готовый ответ. Сам по себе PHP — это интерпретатор, а не сетевой сервер: чтобы страница открылась по адресу, ему нужен слой, который слушает порт. Ниже разберем два разных сценария: встроенный сервер php -S для локальной разработки и связку Apache с PHP для боевого сайта. Отдельно сравним два способа подключить PHP к Apache — mod_php и PHP-FPM — и покажем установку, настройку DocumentRoot, .htaccess и базовую защиту.

Проверено на сентябрь 2026: актуальная стабильная ветка — PHP 8.5 (последний релиз 8.5.10), ветка 8.4 в активной поддержке до конца 2026 года, обновления безопасности для нее — до конца 2028 года; Apache HTTP Server — 2.4.68.

Как PHP исполняется на сервере

Важно сразу развести три сущности, которые новички путают:

  • веб-сервер (Apache, nginx) — слушает порт, принимает HTTP-запрос, отдает ответ;
  • интерпретатор PHP — выполняет код .php и возвращает готовый HTML или иной текст;
  • SAPI (Server API) — интерфейс, через который сервер вызывает интерпретатор.

Один и тот же интерпретатор работает через разные SAPI: cli (запуск из терминала), cli-server (встроенный сервер php -S), fpm-fcgi (PHP-FPM), в старых сборках — модуль Apache (apache2handler). От выбора SAPI зависит, как именно запрос дойдет до вашего кода.

Встроенный сервер php -S: только для разработки

Начиная с PHP 5.4 в интерпретатор встроен простой веб-сервер. Он однопоточный: обрабатывает запросы по одному, и если один запрос завис, остальные ждут. Поэтому он удобен для локальной проверки, но не годится для продакшена.

Запуск из каталога с проектом:

cd ~/public_html
php -S localhost:8000

В консоли появится примерно такой вывод:

[Sat Sep 20 12:00:00 2026] PHP 8.5.10 Development Server (http://localhost:8000) started

Теперь http://localhost:8000/ откроется в браузере. Если URL не указывает на конкретный файл, сервер ищет index.php или index.html в каталоге; если файла нет — вернет код 404. Явно задать корень можно флагом -t:

php -S localhost:8000 -t public/

Здесь только ASCII-дефисы: -S и -t — это обычные короткие флаги, при копировании из статьи они должны остаться дефисами, а не превратиться в типографское тире.

Скрипт маршрутизации

Если после адреса и порта указать PHP-файл, он становится роутером: выполняется в начале каждого запроса. Если роутер возвращает false, сервер отдает запрошенный файл как есть (удобно для картинок и CSS), иначе браузеру уходит вывод скрипта.

<?php
// router.php - скрипт маршрутизации встроенного сервера
$uri = $_SERVER["REQUEST_URI"];
if (preg_match('/\.(?:png|jpg|css|js)$/', $uri)) {
    return false; // отдать статический файл как есть
}
echo "Добро пожаловать";

Запуск: php -S localhost:8000 router.php. Запрос картинки вернет саму картинку, а запрос HTML-страницы — строку «Добро пожаловать». Режим с несколькими воркерами (переменная PHP_CLI_SERVER_WORKERS) существует с PHP 7.4, но помечен как экспериментальный и не работает в Windows — на него тоже не стоит опираться в бою.

mod_php и PHP-FPM: два способа подключить PHP к Apache

Для боевого сайта нужен полноценный веб-сервер. Классический выбор — Apache. Подключить к нему PHP можно двумя способами, и это ключевая развилка статьи.

  • mod_php — PHP встроен в процесс Apache как модуль. Прост в настройке, но требует MPM prefork и держит интерпретатор внутри каждого процесса сервера.
  • PHP-FPM (FastCGI Process Manager) — PHP работает отдельным процессом, а Apache общается с ним по FastCGI через модуль mod_proxy_fcgi. Это рекомендуемый на 2026 год способ.
Критерий mod_php PHP-FPM (через mod_proxy_fcgi)
Где живет PHP внутри процесса Apache отдельный процесс-менеджер
MPM Apache только prefork event или worker (меньше памяти)
Изоляция нет, общее адресное пространство да, свои пулы и свой пользователь
Несколько версий PHP сложно легко: разные пулы и сокеты
Работа с nginx нет да, тот же FPM подходит и для nginx
Статус на 2026 считается устаревшим, не по умолчанию рекомендуемый вариант

Как выбрать: для нового проекта берите PHP-FPM — он экономит память и позволяет держать несколько версий PHP. mod_php осмысленно оставить только в старом окружении, которое дорого перестраивать.

Установка и запуск Apache с PHP-FPM

Пример для Debian/Ubuntu. Имя пакета содержит версию: возьмем php8.4-fpm (стабильная поддерживаемая ветка); при желании ставится и php8.5-fpm.

sudo apt update
sudo apt install apache2 php8.4-fpm
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.4-fpm
sudo systemctl restart apache2

Команды a2enmod и a2enconf включают модуль проксирования FastCGI и готовый конфиг связки. После рестарта Apache будет отдавать .php через FPM. Проверить версию интерпретатора:

php -v
PHP 8.4.13 (cli) (built: ...) 

Если версия ниже ожидаемой — значит, в системе несколько сборок PHP; уточните пакет и путь к сокету FPM (обычно /run/php/php8.4-fpm.sock).

DocumentRoot и виртуальный хост

DocumentRoot — каталог, который Apache считает корнем сайта: путь из URL приклеивается к нему. Хорошая практика — указывать на подкаталог public, чтобы код и конфиги лежали выше корня и не отдавались наружу.

<VirtualHost *:80>
    ServerName example.local
    DocumentRoot /var/www/example/public

    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost"
    </FilesMatch>

    <Directory /var/www/example/public>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Блок FilesMatch направляет файлы .php в PHP-FPM по unix-сокету (поддержка сокетов в mod_proxy_fcgi есть с Apache 2.4.9). Require all granted открывает доступ к каталогу; для служебных папок его меняют на запрет.

.htaccess: локальные правила каталога

.htaccess — файл с настройками Apache для конкретного каталога; он работает, только если в <Directory> разрешен AllowOverride. Типовое применение — «единая точка входа»: все несуществующие пути направить на index.php (front controller).

# public/.htaccess - направить все на index.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]

Условия проверяют, что файла и каталога нет, и только тогда передают управление в index.php. Учтите: .htaccess читается на каждый запрос и немного замедляет сервер, поэтому на нагруженных проектах правила выносят в основной конфиг, а AllowOverride ставят в None.

Обработка запроса: путь от браузера до ответа

Сквозная цепочка на связке Apache + PHP-FPM:

  1. браузер шлет HTTP-запрос GET /page на порт 80/443;
  2. Apache сопоставляет запрос с виртуальным хостом и DocumentRoot;
  3. статический файл (картинку, CSS) Apache отдает сам;
  4. .php по правилу SetHandler уходит в PHP-FPM по сокету;
  5. FPM запускает интерпретатор, тот выполняет код и возвращает ответ;
  6. Apache отдает результат браузеру и пишет строку в лог доступа.

Безопасность: базовый минимум

Первое — не показывать версии Apache и PHP: по ним подбирают известные уязвимости.

ServerTokens Prod
ServerSignature Off

В php.ini отключите заголовок с версией PHP:

expose_php = Off

Второе — права доступа. Не давайте рекурсивный chmod -R 777: это открывает запись всем. Разграничьте права направленно — каталогам 750, файлам 640 — и назначьте владельцем пользователя веб-сервера:

sudo find /var/www/example -type d -exec chmod 750 {} +
sudo find /var/www/example -type f -exec chmod 640 {} +
sudo chown -R www-data:www-data /var/www/example

Третье — держите код и загрузки вне DocumentRoot и включайте HTTPS. Встроенный php -S в открытую сеть не выставляйте: он для локальной разработки.

Выводы

  • PHP — это интерпретатор, а не сетевой сервер; чтобы страница открывалась по адресу, нужен слой, слушающий порт: встроенный php -S или полноценный веб-сервер.
  • Встроенный сервер php -S однопоточный и предназначен только для разработки, в продакшен его не выносят.
  • Для боевого сайта PHP подключают к Apache через PHP-FPM (mod_proxy_fcgi); mod_php на 2026 год считается устаревшим.
  • DocumentRoot стоит направлять на подкаталог public, а разовые правила каталога держать в .htaccess только при разрешенном AllowOverride.
  • Базовая защита: скрыть версии (ServerTokens Prod, expose_php = Off), задать направленные права (750/640) и не открывать dev-сервер в сеть.

Где применяется / связь с практикой

Связка PHP и Apache — это ежедневная рабочая среда backend-разработчика: на ней крутятся сайты на Laravel и Symfony, WordPress, самописные API. Умение поднять локальный php -S, а затем настроить боевой Apache с PHP-FPM, разобраться в DocumentRoot и .htaccess — базовый навык, который спрашивают на собеседованиях и который нужен с первого рабочего дня.

Освойте тему на практике

Системно освоить язык, окружение и деплой можно на курсе PHP-разработчик в Otus. Если хотите сначала посмотреть формат и уровень занятий, загляните на открытые уроки Otus — там разбирают практические темы вживую и отвечают на вопросы.

FAQ

Можно ли использовать php -S в продакшене, если нагрузка небольшая?
Не стоит: встроенный сервер однопоточный, без изоляции и без штатных инструментов защиты. Даже для маленького сайта берите Apache или nginx с PHP-FPM.

Что выбрать для nginx — тоже PHP-FPM?
Да. У nginx нет аналога mod_php, он всегда работает с PHP через FastCGI и PHP-FPM. Тот же пул FPM можно переиспользовать при миграции с Apache на nginx.

Почему после установки Apache отдает код PHP как текст, а не выполняет его?
Значит, обработчик .php не подключен: не включены proxy_fcgi и конфиг FPM, либо в SetHandler указан неверный путь к сокету. Проверьте a2enmod proxy_fcgi, a2enconf php8.4-fpm и перезапустите Apache.

OTUS Журнал
Скидка 5% 12-19 октября на курсы (popup)
Бесплатные открытые уроки (поп-ап)