Суперглобальні змінні
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.13.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-* або Forwarded за RFC 7239):
| Змінна | Значення, коли співрозмовник довірений | Значення в іншому разі |
|---|---|---|
REMOTE_ADDR |
Крайня праворуч недовірена адреса з X-Forwarded-For / Forwarded; CF-Connecting-IP для запиту, чий ланцюжок переспрямування показує, що він надійшов із периферійного вузла Cloudflare, коли TRUSTED_PROXIES містить cloudflare; безпосередній співрозмовник, якщо переспрямувальні заголовки не дають адреси |
IP безпосереднього співрозмовника |
REMOTE_PORT |
Вихідний порт клієнта з елемента ip:port у Forwarded або X-Forwarded-For, інакше 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 — це вихідний порт клієнта, якщо елемент, з якого взято адресу, його містить (вузол RFC 7239 Forwarded: for="ip:port" або елемент ip:port у X-Forwarded-For), і "0" в іншому разі: значення обнуляється, а не вгадується. Адреса, взята з CF-Connecting-IP, теж не містить порту, тож тоді REMOTE_PORT дорівнює "0", навіть якщо Forwarded його має. Коли переспрямувальні заголовки не дають адреси клієнта (див. Визначення IP-адреси клієнта), ні REMOTE_ADDR, ні REMOTE_PORT не переписуються: обидва лишаються значеннями безпосереднього співрозмовника.
Якщо 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"]filter_input(), filter_input_array() і filter_has_var() не читають $_GET, $_POST чи $_COOKIE. Розширення filter тримає власну копію розібраних вхідних даних, і в постійному воркері цю копію заповнює кожен запит — тож кожен запит мусить її й повертати, інакше параметри запиту, сесійні cookie та поля тіла одного клієнта лишаються доступними для кожного наступного запиту, який обслуговує воркер. OxPHP повертає її на початку кожного запиту, тож ці три функції відповідають лише для того запиту, що їх викликає, і ні для якого іншого.
Режим воркера додає одне обмеження. Якщо ваш запит призупиняється (sleep(), await, перехоплений виклик) і за цей час на тому самому воркері виконується інший запит, сховище переходить до того запиту. Після відновлення читання повертають null, а не чужі вхідні дані, але копії, яку мав ваш запит, на той момент уже немає. Для цього достатньо, щоб інший запит там почався або відновився, — завершуватися йому не обов’язково. $_GET, $_POST і $_COOKIE переходять разом із запитом через призупинення і цього не зазнають, тож читайте їх — або викликайте функції filter до призупинення.
Один виклик призупинятися не може взагалі. filter_input_array() із масивом визначень для окремих полів читає сховище по разу на кожне поле, тож FILTER_CALLBACK, що виконує введення-виведення, працює, утримуючи воркер на весь час виконання, замість того щоб передати його іншому запиту, а явний Fiber::suspend() усередині такого зворотного виклику кидає виняток. Очікування все одно відбувається — тільки чекає потік воркера, а не запит, — тож повільний зворотний виклик проявляється як затримка для всього, що стоїть у черзі за ним, а запити в черзі, що вичерпали свій бюджет очікування, відкидаються. Скільки це може тривати, визначає не сервер, а те, з чим працює зворотний виклик: обгортка потоку здається через default_socket_timeout (типово 60 секунд), тоді як mysqlnd чекає mysqlnd.net_read_timeout (типово добу). Задайте такому виклику явний тайм-аут — а краще виконуйте перевірку, що звертається до бази даних чи кешу, над значенням уже після того, як filter_input_array() його повернула.
$_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"filter_input(INPUT_POST, …) читає не $_POST, а власну копію тіла в розширенні filter — що це за копія і скільки вона живе, пояснює примітка в розділі $_GET.
$_COOKIE
Cookie розбираються із заголовка запиту Cookie.
<?php
// Request with: Cookie: session=abc123; theme=dark
$session = $_COOKIE['session']; // "abc123"
$theme = $_COOKIE['theme']; // "dark"Cookie з префіксом __oxp_ зарезервовано для внутрішніх плагінів OxPHP. Їх вилучають із заголовка Cookie ще до того, як він потрапить до PHP, тож у $_COOKIE вони не з’являться.
filter_input(INPUT_COOKIE, …) читає не $_COOKIE, а власну копію cookie в розширенні filter — що це за копія і скільки вона живе, пояснює примітка в розділі $_GET.
$_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 або variables_order, якщо request_order не задано. Саме об’єднання відбувається за незмінними правилами PHP: джерела зливаються в тому порядку, в якому їх перелічує директива, і пізніше джерело перезаписує ключ, встановлений раніше.
Образи OxPHP не завантажують жодного php.ini: php.ini-production і php.ini-development лежать у /usr/local/etc/php невикористаними (див. Встановлення). Через це request_order не задано, і PHP повертається до вбудованого значення variables_order, "EGPCS": спершу GET, потім POST, потім COOKIE. Отже, cookie замінює однойменне значення з рядка запиту чи тіла; коли обидва значення є масивами (k[a] у тілі, k[b] у cookie), вони зливаються поключово за тим самим правилом.
Знайоме вам із налаштувань PHP-FPM request_order = "GP" походить зі зразків php.ini-production і php.ini-development, а не з самого PHP. Щоб виключити cookie, задайте його в ini-файлі, що завантажується під час запуску, наприклад у /usr/local/etc/php/conf.d/zz-request-order.ini з вмістом request_order = "GP". Змінити цю директиву під час виконання через ini_set() не можна.
<?php
// POST /form?action=preview with body action=submit
$action = $_REQUEST['action']; // "submit" — POST overrides GET
// Same request, also carrying the header "Cookie: action=delete"
$action = $_REQUEST['action']; // "delete" — the cookie overrides both$_REQUEST будується заново для кожного запиту. Зазвичай PHP будує його ліниво, один раз, коли вперше завантажується скрипт, що його згадує, — а в постійному воркері це означало б, що кожен наступний запит читає параметри першого. OxPHP натомість примусово перебудовує його, тож об’єднаний масив завжди описує запит, який обслуговується.
$_ENV
$_ENV містить оточення процесу. У традиційному режимі він поводиться точно так, як у PHP-FPM: PHP заново заповнює його з оточення на кожному запиті з урахуванням variables_order.
Режим воркера його закріплює. Воркер ініціалізується один раз, а завантажувачі .env (vlucas/phpdotenv, symfony/dotenv, Env у Laravel) записують свої значення просто в $_ENV, не торкаючись оточення процесу. Якби $_ENV заповнювався заново на кожному запиті, конфігурація застосунку зникала б, починаючи з другого запиту, тому в режимі воркера масив, щойно він з’явився, зберігається протягом усього життя воркера. Записи, які робить туди ваш код ініціалізації, лишаються видимими для кожного запиту, що його обслуговує цей воркер, — як і будь-який інший запис туди; що це означає всередині обробника запиту, пояснює попередження під прикладом.
<?php
// bootstrap, before oxphp_worker()
Dotenv\Dotenv::createImmutable(__DIR__)->load(); // writes into $_ENV
oxphp_worker(function () {
echo $_ENV['DATABASE_URL']; // still there on request 10_000
});Механізм лише закріплює масив, тож він не відрізняє запис під час ініціалізації від запису в обробнику: $_ENV['tenant_id'] = $request->tenant(); усередині обробника запиту лишається в $_ENV до кінця життя воркера. Його читає кожен наступний запит, який обслуговує цей воркер. Так само його читає й запит, який воркер бере в роботу, поки запит, що записав значення, стоїть в одній із точок призупинення, бо $_ENV навмисно не входить до стану, який призупинений запит несе із собою, і тоді обидва читають той самий масив. Жоден із цих випадків ніяк не повідомляється. Не буде ні попередження, ні запису в журналі: запит просто читає значення, яке встановив інший запит.
Записуйте в $_ENV лише з коду ініціалізації і більше ніде. Значення, що стосується одного запиту, зберігайте там, що будується заново для кожного запиту. $_SERVER саме такий, і він переходить через призупинення разом зі своїм запитом. Підійде й усе, що ваш фреймворк прив’язує до запиту, але перевірте, що воно прив’язане саме до запиту, а не до воркера: прив’язка в контейнері чи стек запитів, налаштовані один раз під час ініціалізації, — це стан воркера з тим самим охопленням, що й у $_ENV. Підійде й контейнер атрибутів власного об’єкта запиту OxPHP, якщо ви передаєте цей об’єкт далі: oxphp_http_request() на кожен виклик створює новий Request, а разом із ним — новий порожній контейнер.
filter_input(INPUT_ENV, …), filter_input_array(INPUT_ENV) і filter_has_var(INPUT_ENV, …) у режимі воркера читають оточення процесу. $_ENV вони не читають, тож значень, записаних туди вашим кодом ініціалізації чи будь-чим іншим, серед них немає. Так PHP поводиться скрізь, бо запис у $_ENV дає масиву власну копію, а розширення filter і далі читає знімок оточення, зроблений рушієм. Режим воркера додає один нюанс: знімок — той, що зроблено, коли $_ENV уперше будувався на воркері, тож виклику putenv(), зробленого пізніше, у ньому теж немає. getenv() читає живе оточення і цього не зазнає; $_ENV містить значення процесу плюс усе, що PHP на цьому воркері туди записав. Усе це стосується лише INPUT_ENV: INPUT_GET, INPUT_POST і INPUT_COOKIE читають власне сховище всередині розширення filter, описане в примітці до розділу $_GET вище.
Закріплення спирається на типове для PHP значення auto_globals_jit=1. За auto_globals_jit=0 PHP заново заповнює $_ENV з оточення процесу на кожному запиті ще до того, як будь-яке розширення встигне втрутитися, і значення завантажувача .env у режимі воркера не збережуться.
php://input
Сире тіло запиту доступне через потік php://input. Це стандартний спосіб читати JSON, XML чи будь-який інший тип вмісту, крім надсилання форм.
<?php
$body = file_get_contents('php://input');
$data = json_decode($body, true);php://input можна перемотувати й читати кілька разів у межах одного запиту.
Для запитів multipart/form-data потік php://input порожній. Для них використовуйте $_POST і $_FILES.
Вимкнення суперглобальних змінних
Задайте SUPERGLOBALS_ENABLED=false, щоб OxPHP перестав описувати запит для PHP: змінні CGI та HTTP_* не реєструються, а рядок запиту не передається на розбір. Натомість отримуйте дані запиту через HTTP Request API (oxphp_http_request()).
SUPERGLOBALS_ENABLED=false # the $_SERVER request keys and $_GET are not builtНалаштування зачіпає менше цих масивів, ніж підказує назва. Тіло запиту й заголовок Cookie передаються до PHP у будь-якому разі, тож усе, що PHP будує з них, на місці як завжди:
| Що | За SUPERGLOBALS_ENABLED=false |
|---|---|
$_GET |
Порожній |
$_SERVER |
Під час запиту — лише чотири ключі: REQUEST_TIME, REQUEST_TIME_FLOAT, argc і argv, які реєструє сам PHP, а не сервер. REQUEST_METHOD, REQUEST_URI, ключів HTTP_* і оточення процесу немає. У режимі воркера ініціалізація відбувається інакше: код над oxphp_worker() виконується до будь-якого запиту й бачить $_SERVER, побудований так, ніби налаштування ввімкнене, разом з усім оточенням процесу, плюс заглушку REQUEST_URI зі значенням / |
$_POST, $_FILES, $_COOKIE |
Заповнюються як завжди |
$_REQUEST |
Заповнюється, PHP об’єднує його як завжди (див. $_REQUEST); бракує лише того, що додав би $_GET |
$_SESSION |
Заповнює модуль сесій PHP, коли запит запускає сесію, а не SAPI |
php://input |
Потік, а не суперглобальна змінна; читається як завжди |
header(), headers_list() тощо |
Функції SAPI, а не суперглобальні змінні |
session_start() та інші функції session_*() |
Вбудовані функції PHP |
oxphp_http_request() |
Доступна; відповідає кожен метод, зокрема query() і payload() |
Код, що маршрутизує за $_SERVER['REQUEST_URI'], за цього налаштування нічого там не знайде і має натомість читати oxphp_http_request()->path(). У вхідному скрипті воркера це стосується обробника. Код ініціалізації над ним бачить описану в таблиці заглушку /, яка теж не є справжнім маршрутом.
Поточне значення налаштування можна перевірити під час виконання:
if (!oxphp_superglobals_enabled()) {
$request = oxphp_http_request();
$page = $request->query('page', 1);
}Промпти для вашого агента
Ці промпти розраховані на агента з підключеним MCP-сервером документації OxPHP — потрібні сторінки він прочитає сам.
Перевір, як мій код читає суперглобальні змінні, на предмет відмінностей між OxPHP і PHP-FPM. Прочитай сторінку `php/superglobals` через MCP-сервер документації OxPHP.
Перевір мій застосунок на читання `$_SERVER['PHP_AUTH_USER']`, `SERVER_ADDR` або `PATH_TRANSLATED` і на код Basic-Auth, який очікує, що їх уже розібрано, а потім скажи, які з цих читань треба змінити і на що.Мій застосунок у режимі воркера OxPHP втрачає значення, які він читав через `filter_input()`. Прочитай сторінку `php/superglobals` через MCP-сервер документації OxPHP.
Перевір мій код на виклики `filter_input()` і `filter_input_array()`, що призупиняються на введенні-виведенні або на призупиненому Fiber, і скажи, які з них вразливі до описаних на сторінці перегонів у режимі воркера, коли відновлений запит читає сховище іншого запиту.Див. також
- HTTP Request API -- типізований об’єкт запиту з лінивим завантаженням як альтернатива суперглобальним змінним
- Функції PHP --
oxphp_request_id(),oxphp_worker_id()та інші функції розширення - Режим воркера -- як суперглобальні змінні оновлюються між запитами воркера
- Довідник із конфігурації --
DOCUMENT_ROOTта інші змінні конфігурації сервера