Суперглобальные переменные
OxPHP заполняет все стандартные суперглобальные переменные PHP до выполнения вашего скрипта, воспроизводя поведение, которое PHP-разработчики ожидают от традиционной серверной конфигурации. Значения доступны с первой строки вашего кода и не требуют какой-либо инициализации.
$_SERVER
OxPHP формирует $_SERVER из входящего HTTP-запроса в соответствии со спецификацией CGI/1.1. Сначала импортируются переменные окружения процесса, затем задаются CGI-переменные, поэтому значения, специфичные для запроса, всегда переопределяют совпадающие по имени ключи окружения.
Стандартные переменные
| Переменная | Описание | Пример |
|---|---|---|
SCRIPT_FILENAME |
Абсолютный путь в файловой системе к исполняемому PHP-скрипту | /var/www/html/public/index.php |
DOCUMENT_ROOT |
Корневой веб-каталог, задаваемый переменной окружения DOCUMENT_ROOT |
/var/www/html/public |
SERVER_SOFTWARE |
Идентификатор сервера (содержит версию запущенного OxPHP) | OxPHP/0.10.0 |
SERVER_PROTOCOL |
Согласованная версия протокола HTTP | HTTP/2 |
REQUEST_METHOD |
HTTP-метод | GET |
REQUEST_URI |
Полный URI со строкой запроса | /app?page=2 |
SCRIPT_NAME |
Путь исполняемого скрипта относительно DOCUMENT_ROOT — фронт-контроллер в режиме Framework, а не URI запроса |
/index.php |
DOCUMENT_URI |
Псевдоним SCRIPT_NAME, для совместимости с nginx/PHP-FPM |
/index.php |
PHP_SELF |
SCRIPT_NAME плюс PATH_INFO, если он присутствует, иначе равен SCRIPT_NAME |
/index.php/user/42 |
QUERY_STRING |
Часть URI, содержащая строку запроса (пустая строка при отсутствии) | page=2 |
SERVER_NAME |
Имя хоста из заголовка Host |
example.com |
SERVER_PORT |
Порт из заголовка Host |
8080 |
REMOTE_ADDR |
IP-адрес клиента | 172.17.0.1 |
REMOTE_PORT |
Номер порта клиента | 54321 |
HTTPS |
Устанавливается в "on", когда соединение использует TLS; иначе отсутствует |
on |
REQUEST_SCHEME |
"https" для TLS-соединений, иначе "http" |
https |
CONTENT_TYPE |
Значение заголовка Content-Type (без префикса HTTP_) |
application/json |
CONTENT_LENGTH |
Значение заголовка Content-Length (без префикса HTTP_) |
128 |
REQUEST_TIME |
Unix-время (целое число) начала запроса | 1738800000 |
REQUEST_TIME_FLOAT |
Unix-время с точностью до микросекунд | 1738800000.123456 |
GATEWAY_INTERFACE |
Строка версии CGI | CGI/1.1 |
Если заголовок Host отсутствует, SERVER_NAME по умолчанию принимает значение localhost, а SERVER_PORT — 80 (или 443 для TLS).
Заголовки HTTP-запроса
Все заголовки HTTP-запроса добавляются в $_SERVER с префиксом HTTP_. Имена заголовков приводятся к верхнему регистру, а дефисы заменяются подчёркиваниями — по соглашениям CGI/1.1:
Accept: text/html -> HTTP_ACCEPT
X-Forwarded-For: 1.2.3.4 -> HTTP_X_FORWARDED_FOR
Authorization: Bearer abc -> HTTP_AUTHORIZATION
Cookie: session=xyz -> HTTP_COOKIEContent-Type и Content-Length появляются без префикса HTTP_ — как CONTENT_TYPE и CONTENT_LENGTH — как того требует спецификация CGI.
За обратным прокси
Когда настроен TRUSTED_PROXIES и узел, от которого поступил запрос, входит в доверенный набор, OxPHP перезаписывает следующие ключи $_SERVER из проброшенных заголовков (X-Forwarded-* или RFC 7239 Forwarded):
| Переменная | Значение, когда узел доверенный | Значение в остальных случаях |
|---|---|---|
REMOTE_ADDR |
Самый правый недоверенный адрес из X-Forwarded-For / Forwarded |
IP непосредственного узла |
REMOTE_PORT |
Исходный порт клиента из Forwarded: for=ip:port, иначе 0 |
Порт непосредственного узла |
HTTPS |
"on", если X-Forwarded-Proto: https |
Устанавливается только когда соединение с узлом использует TLS |
REQUEST_SCHEME |
"https" / "http" из X-Forwarded-Proto |
На основе фактического состояния TLS |
SERVER_NAME |
Часть с именем хоста из X-Forwarded-Host |
Часть с именем хоста из заголовка Host |
SERVER_PORT |
X-Forwarded-Port, иначе часть с портом из X-Forwarded-Host, иначе 443/80 по схеме |
Часть с портом из Host, либо 443/80 |
Исходные ключи HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED_PROTO, HTTP_X_FORWARDED_HOST, HTTP_X_FORWARDED_PORT и HTTP_FORWARDED остаются в $_SERVER без изменений — доступны и перезаписанные значения, и исходные заголовки.
REMOTE_PORT равен "0" за доверенным прокси, если только прокси не присылает RFC 7239 Forwarded: for=ip:port — ни X-Forwarded-For, ни выбор самого правого недоверенного адреса не несут исходного порта клиента, поэтому синтетическое значение обнуляется, а не угадывается.
Когда TRUSTED_PROXIES не задан, перезапись не выполняется, и REMOTE_ADDR всегда равен непосредственному узлу — обычно это ваш балансировщик нагрузки, а не конечный клиент. Разбирать X-Forwarded-For вручную чревато ошибками (крайний левый или крайний правый адрес, отсутствие проверки доверия по CIDR); предпочтительнее настроить TRUSTED_PROXIES. См. Доверенные прокси, где описаны алгоритм доверия и синтаксис настройки.
Переменные контекста трассировки
Когда включена распределённая трассировка, OxPHP добавляет в $_SERVER переменные контекста трассировки:
| Переменная | Описание | Пример |
|---|---|---|
OXPHP_TRACE_ID |
Идентификатор трассировки W3C для текущего запроса | 4bf92f3577b34da6a3ce929d0e0e4736 |
OXPHP_SPAN_ID |
Идентификатор спана для серверного спана OxPHP | 00f067aa0ba902b7 |
OXPHP_PARENT_SPAN_ID |
Идентификатор родительского спана от вышестоящего сервиса (пусто, если это корень) | b9c7c989f97918e1 |
Эти переменные присутствуют только когда приходит корректный заголовок traceparent или когда OxPHP генерирует новую трассировку. Если трассировка не настроена, эти ключи отсутствуют.
Отличия от PHP-FPM
Следующие переменные ведут себя иначе, чем в стандартной конфигурации PHP-FPM:
| Переменная | Поведение |
|---|---|
SERVER_ADDR |
Не устанавливается. OxPHP не заполняет локальный IP-адрес сервера. |
PATH_INFO |
Устанавливается автоматически — см. Поведение PATH_INFO ниже. |
PATH_TRANSLATED |
Не устанавливается. |
PHP_AUTH_USER / PHP_AUTH_PW / AUTH_TYPE |
Не извлекаются из заголовка Authorization. Читайте $_SERVER['HTTP_AUTHORIZATION'] напрямую. |
REDIRECT_STATUS |
Не устанавливается. OxPHP не использует внутренний механизм перенаправления. |
Пример
<?php
$method = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
$ip = $_SERVER['REMOTE_ADDR'];
$host = $_SERVER['SERVER_NAME'];
$scheme = $_SERVER['REQUEST_SCHEME']; // "http" or "https"
// Read a custom header
$token = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
// REMOTE_ADDR is already the real client IP when TRUSTED_PROXIES is configured.
// Without it, REMOTE_ADDR is the direct peer (usually a load balancer).
$clientIp = $_SERVER['REMOTE_ADDR'];
// Check TLS without checking the port
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
// Secure connection
}Поведение PATH_INFO
$_SERVER['PATH_INFO'] заполняется автоматически в зависимости от активного режима маршрутизации. Никакого флага для этого нет — прежняя переменная окружения SPLIT_PATH_INFO_ENABLED была удалена.
| Режим маршрутизации | Когда устанавливается | Значение |
|---|---|---|
Traditional (ENTRY_FILE не задан) |
Только когда URI содержит .php/ и префикс скрипта существует на диске |
Хвост после сегмента скрипта |
Framework (ENTRY_FILE=index.php) |
Только когда запрос явно указывает входной файл с завершающим сегментом (/index.php/extra) |
Хвост после входного файла, например /news |
SPA (ENTRY_FILE=index.html) |
Никогда — PHP выполняется только для точных .php-файлов, без PATH_INFO |
— |
SCRIPT_NAME всегда указывает на исполняемый скрипт (разрешённый файл относительно корневого каталога документов), поэтому при обычной маршрутизации PATH_INFO присутствует только тогда, когда SCRIPT_NAME является буквальным префиксом пути запроса. Когда запрос переписывается на фронт-контроллер, который в нём не назван (маршрут приложения, индекс каталога, запасной вариант при промахе по статике), PATH_INFO отсутствует, а исходный путь хранится в REQUEST_URI. (Запасной вариант PHP_DENY_PATHS — намеренное исключение: он устанавливает PATH_INFO равным исходному очищенному URI, чтобы запасной скрипт мог по нему маршрутизировать.)
Примеры режима Traditional
OxPHP сканирует URI слева направо в поисках первого сегмента .php, которому соответствует реальный файл на диске. Всё, что идёт после него, становится PATH_INFO:
| URI запроса | Файл на диске | SCRIPT_NAME |
PATH_INFO |
PHP_SELF |
|---|---|---|---|---|
/app.php/user/42 |
app.php существует |
/app.php |
/user/42 |
/app.php/user/42 |
/index.php/api/v2/users |
index.php существует |
/index.php |
/api/v2/users |
/index.php/api/v2/users |
/app.php |
app.php существует |
/app.php |
(отсутствует) | /app.php |
/missing.php/foo |
файл не найден | откат к /index.php |
— | зависит от отката |
Примеры режима Framework
Каждый нестатический запрос переписывается на index.php. PATH_INFO устанавливается только тогда, когда запрос явно указывает входной файл с завершающим сегментом; для маршрутов приложения исходный путь читается из REQUEST_URI.
| URI запроса | SCRIPT_NAME |
PATH_INFO |
|---|---|---|
/api/users |
/index.php |
(отсутствует) |
/about.php |
/index.php |
(отсутствует) |
/index.php/news/local |
/index.php |
/news/local |
/index.php |
/index.php |
(отсутствует) |
PATH_TRANSLATED не заполняется. На практике он используется редко и по умолчанию не устанавливается ни nginx, ни PHP-FPM.
$_GET
Параметры строки запроса автоматически разбираются из URI запроса.
<?php
// Request: GET /search?q=oxphp&page=2
$query = $_GET['q']; // "oxphp"
$page = $_GET['page']; // "2"Синтаксис массивов работает как ожидается:
<?php
// Request: GET /filter?tags[]=php&tags[]=async
$tags = $_GET['tags']; // ["php", "async"]$_POST
OxPHP поддерживает два стандартных типа содержимого для отправки форм:
application/x-www-form-urlencoded— стандартные данные HTML-формыmultipart/form-data— загрузка файлов в сочетании с полями формы
<?php
// Request: POST /login
// Content-Type: application/x-www-form-urlencoded
// Body: username=admin&password=secret
$username = $_POST['username']; // "admin"
$password = $_POST['password']; // "secret"Для JSON или других типов содержимого используйте вместо этого php://input:
<?php
// Request: POST /api/users
// Content-Type: application/json
// Body: {"name":"Alice","email":"alice@example.com"}
$data = json_decode(file_get_contents('php://input'), true);
$name = $data['name']; // "Alice"
$email = $data['email']; // "alice@example.com"$_COOKIE
Куки разбираются из заголовка запроса Cookie.
<?php
// Request with: Cookie: session=abc123; theme=dark
$session = $_COOKIE['session']; // "abc123"
$theme = $_COOKIE['theme']; // "dark"Куки с префиксом __oxp_ зарезервированы для внутренних плагинов OxPHP. Они удаляются из заголовка Cookie до того, как он достигнет PHP, и не появляются в $_COOKIE.
$_FILES
Загруженные файлы, отправленные через multipart/form-data, заполняют массив $_FILES стандартной для PHP структурой:
<?php
// $_FILES['avatar'] structure:
// [
// 'name' => 'photo.jpg', // Original filename sent by the client
// 'type' => 'image/jpeg', // MIME type declared by the client
// 'tmp_name' => '/tmp/phpAb12Cd', // Temporary file path on the server
// 'error' => 0, // UPLOAD_ERR_OK (0 means no error)
// 'size' => 204800, // File size in bytes
// ]
if ($_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
$tmp = $_FILES['avatar']['tmp_name'];
$name = basename($_FILES['avatar']['name']);
move_uploaded_file($tmp, "/uploads/$name");
}$_REQUEST
$_REQUEST — это объединённый массив из $_GET, $_POST и, опционально, $_COOKIE, формируемый PHP согласно INI-директиве request_order (по умолчанию: "GP" — сначала GET, затем POST). OxPHP не изменяет это поведение.
<?php
// GET /form?action=preview with POST body: action=submit
$action = $_REQUEST['action']; // "submit" (POST overrides GET with default order)php://input
Необработанное тело запроса доступно через поток php://input. Это стандартный способ читать полезную нагрузку JSON, XML или любой тип содержимого, отличный от отправки форм.
<?php
$body = file_get_contents('php://input');
$data = json_decode($body, true);php://input можно перематывать и читать несколько раз в рамках одного запроса.
php://input пуст для запросов multipart/form-data. Для них используйте $_POST и $_FILES.
Отключение суперглобальных переменных
Задайте SUPERGLOBALS_ENABLED=false, чтобы отключить заполнение $_GET, $_POST, $_COOKIE, $_FILES и $_SERVER. Когда отключено, эти массивы пусты. Для доступа к данным запроса используйте вместо этого HTTP Request API (oxphp_http_request()).
SUPERGLOBALS_ENABLED=false # superglobals are empty arraysСледующее остаётся доступным независимо от этой настройки:
| Что | Почему |
|---|---|
$_SESSION |
Управляется модулем сессий PHP, а не SAPI |
php://input |
Поток, а не суперглобальная переменная |
header(), headers_list() и т. д. |
Функции SAPI, а не суперглобальные переменные |
session_start() и другие функции session_*() |
Нативные функции PHP |
oxphp_http_request() |
Всегда доступна — рекомендуемая альтернатива |
Текущую настройку можно проверить во время выполнения:
if (!oxphp_superglobals_enabled()) {
$request = oxphp_http_request();
$page = $request->query('page', 1);
}См. также
- HTTP Request API -- типизированный, лениво загружаемый объект запроса как альтернатива суперглобальным переменным
- Функции PHP --
oxphp_request_id(),oxphp_worker_id()и другие функции расширения - Режим воркеров -- как суперглобальные переменные обновляются между запросами воркера
- Справочник по конфигурации --
DOCUMENT_ROOTи другие переменные конфигурации сервера