PHP-функции
OxPHP регистрирует свои функции через расширение oxphp_sapi, которое автоматически загружается для каждого PHP-скрипта, выполняемого сервером. Директива extension= и ручная загрузка не требуются. Все перечисленные здесь функции доступны с первой строки вашего PHP-кода.
Оглавление
- oxphp_http_request()
- oxphp_superglobals_enabled()
- oxphp_request_id()
- oxphp_worker_id()
- oxphp_server_info()
- oxphp_finish_request()
- oxphp_is_worker()
- oxphp_worker()
- oxphp_is_streaming()
- oxphp_stream_flush()
- oxphp_sleep()
- oxphp_usleep()
- oxphp_async()
- oxphp_async_await()
- oxphp_async_await_all()
- oxphp_async_await_race()
- oxphp_async_await_any()
- oxphp_register_decorator()
- oxphp_apm_trace()
- oxphp_apm_start()
- oxphp_apm_end()
- oxphp_apm_attribute()
- oxphp_apm_event()
- oxphp_apm_error()
- oxphp_apm_status()
- oxphp_apm_trace_id()
- oxphp_apm_span_id()
- oxphp_apm_header()
- OxPHP\Profile\is_active()
- OxPHP\Profile\start()
- OxPHP\Profile\stop()
- OxPHP\Profile\pause()
- OxPHP\Profile\resume()
- OxPHP\Profile\mark()
- OxPHP\Profile\metric()
- Классы и интерфейсы
- Исключения
oxphp_http_request()
oxphp_http_request(): \OxPHP\Http\RequestВозвращает объект запроса для текущего HTTP-запроса. Объект предоставляет типизированный доступ к HTTP-методу, URI, параметрам строки запроса, разобранному телу, заголовкам, cookie, загруженным файлам, IP клиента и таймингам запроса.
Возвращает: экземпляр \OxPHP\Http\Request, опирающийся на данные запроса в текущем PHP-потоке воркера.
Выбрасывает: исключение из пространства имён OxPHP\Http\Exception, если вызвана вне активного запроса:
| Исключение | Ситуация |
|---|---|
\OxPHP\Http\Exception\WorkerIdleException |
Режим воркеров, между запросами |
\OxPHP\Http\Exception\AsyncContextException |
Внутри колбэка oxphp_async() |
\OxPHP\Http\Exception\NoActiveRequestException |
Любой другой контекст без активного запроса |
В обычном коде обработки запроса обработка исключений не требуется.
Пример:
<?php
$request = oxphp_http_request();
$method = $request->method(); // "POST"
$path = $request->path(); // "/api/users"
$email = $request->payload('email'); // from JSON or form body
$token = $request->header('Authorization');
$theme = $request->cookie('theme', 'light');Полный справочник по интерфейсу см. в документации HTTP Request API.
oxphp_superglobals_enabled()
oxphp_superglobals_enabled(): boolВозвращает, включено ли заполнение суперглобальных переменных для этого экземпляра сервера. Значение отражает переменную окружения SUPERGLOBALS_ENABLED и не меняется в течение всего времени работы сервера.
Когда значение false, $_GET, $_POST, $_COOKIE, $_FILES и $_SERVER являются пустыми массивами. Это не влияет на HTTP Object API (oxphp_http_request()), php://input и функции сессий PHP.
Возвращает: true, когда SUPERGLOBALS_ENABLED равно true (значение по умолчанию), иначе false.
Пример:
<?php
if (oxphp_superglobals_enabled()) {
$query = $_GET['page'] ?? 1;
} else {
$query = oxphp_http_request()->query('page', 1);
}oxphp_request_id()
oxphp_request_id(): stringВозвращает уникальный идентификатор текущего запроса. Это то же значение, что отправляется в заголовке ответа X-Request-ID. Если клиент присылает заголовок X-Request-ID, OxPHP пропускает его без изменений вместо генерации нового.
Возвращает: 20-символьную шестнадцатеричную строку, когда идентификатор генерирует OxPHP (например, "67890abc12341a2b0042"). Когда клиент присылает заголовок X-Request-ID, это значение возвращается как есть (1–64 символа, буквы и цифры плюс -, _, .).
Пример:
<?php
$id = oxphp_request_id();
error_log("[$id] Processing order #1234");
// Propagate the ID to downstream services
header("X-Correlation-ID: $id");oxphp_worker_id()
oxphp_worker_id(): intВозвращает индекс (отсчёт с нуля) PHP-потока воркера, обрабатывающего текущий запрос. Индексы воркеров находятся в диапазоне от 0 до PHP_WORKERS - 1.
Возвращает: целое число, идентифицирующее текущий поток воркера.
Пример:
<?php
$workerId = oxphp_worker_id();
// Use per-worker temp files to avoid collisions
$tmp = "/tmp/worker_{$workerId}_buffer.dat";
error_log("Worker $workerId handling request");oxphp_server_info()
oxphp_server_info(): arrayВозвращает ассоциативный массив с метаданными сервера и запроса.
Возвращает: массив со следующими ключами:
| Ключ | Тип | Описание |
|---|---|---|
version |
string |
Версия сервера (например, "0.10.0") |
worker_id |
int |
То же значение, что и oxphp_worker_id() |
request_time |
float |
Unix-метка времени с микросекундной точностью, когда начался запрос |
worker_mode |
bool |
Работает ли текущий процесс в режиме воркеров |
Пример:
<?php
$info = oxphp_server_info();
// [
// "version" => "0.10.0",
// "worker_id" => 3,
// "request_time" => 1738800000.123456,
// "worker_mode" => true,
// ]
$elapsed = microtime(true) - $info['request_time'];
echo "Processing took {$elapsed}s so far";oxphp_finish_request()
oxphp_finish_request(): boolСбрасывает ответ клиенту и продолжает выполнение PHP в фоне. Клиент немедленно получает полный HTTP-ответ; скрипт продолжает работать, пока не завершится естественным образом. Это аналог fastcgi_finish_request() из PHP-FPM в OxPHP.
Возвращает: true при успехе, false, если функция уже была вызвана для этого запроса.
PHP-поток воркера остаётся занятым, пока скрипт не завершится. Держите фоновую работу короткой или выносите тяжёлую обработку в очередь.
Пример:
<?php
http_response_code(202);
echo json_encode(['status' => 'accepted']);
oxphp_finish_request();
// The client already has its 202 response; continue working
send_notification_email($user);
update_analytics($event);oxphp_is_worker()
oxphp_is_worker(): boolВозвращает, работает ли сервер в режиме воркеров. Режим воркеров активируется, когда WORKER_MODE_ENABLED=true.
Возвращает: true, если сервер работает в режиме воркеров, false — в традиционном режиме.
Пример:
<?php
if (oxphp_is_worker()) {
// Reuse persistent connections across requests
$db = $GLOBALS['db'] ??= new PDO($dsn);
} else {
// Traditional mode: create a new connection per request
$db = new PDO($dsn);
}oxphp_worker()
oxphp_worker(callable $handler): boolВходит в цикл постоянного режима воркеров. OxPHP вызывает $handler по одному разу для каждого входящего HTTP-запроса. Между запросами мягкий сброс очищает состояние на уровне запроса — буферы вывода, заголовки и суперглобальные переменные — не разрушая кучу PHP, поэтому любые переменные, объявленные вне обработчика, сохраняются между запросами.
Параметры:
$handler— вызывается по одному разу на запрос. Обработчик не получает аргументов. Используйте суперглобальные переменные ($_SERVER,$_GET,$_POSTи т. д.) илиoxphp_http_request()внутри обработчика для доступа к данным запроса.
Возвращает: true при корректном завершении работы, false, если сервер не в режиме воркеров.
Цикл воркера завершается при выполнении любого из следующих условий:
- Сервер корректно завершает работу
- Обработчик выбрасывает 3 необработанных исключения или фатальные ошибки подряд
- Воркер превышает
WORKER_MAX_MEMORY_MIB - Приложение вызывает
Worker::scheduleExit()
oxphp_worker() работает только в режиме воркеров (WORKER_MODE_ENABLED=true). В традиционном режиме она пишет предупреждение в лог и возвращает false.
Пример:
<?php
// worker.php — runs once per worker process lifetime
// Bootstrap: executed once on startup
require __DIR__ . '/vendor/autoload.php';
$app = new App();
// Handle requests in a loop
oxphp_worker(function () use ($app) {
$app->handle();
});
// Code after oxphp_worker() runs during shutdown
$app->terminate();oxphp_is_streaming()
oxphp_is_streaming(): boolВозвращает, находится ли текущий запрос в потоковом режиме. Потоковый режим активируется при первом вызове oxphp_stream_flush() или автоматически, когда PHP устанавливает Content-Type: text/event-stream.
Возвращает: true, если потоковый режим активен, иначе false.
Пример:
<?php
if (oxphp_is_streaming()) {
echo "data: " . json_encode($event) . "\n\n";
oxphp_stream_flush();
} else {
echo json_encode($allData);
}oxphp_stream_flush()
oxphp_stream_flush(): boolАктивирует потоковый режим и сбрасывает любой буферизованный вывод клиенту в виде HTTP-чанка. При первом вызове HTTP-заголовки отправляются немедленно и начинается потоковая передача. Каждый последующий вызов сбрасывает вывод, записанный со времени предыдущего сброса.
Возвращает: true при успехе, false, если oxphp_finish_request() уже была вызвана.
Потоковый режим также активируется автоматически, когда PHP устанавливает Content-Type: text/event-stream. В этом случае можно использовать встроенную функцию PHP flush(), но сначала вызовите ob_end_flush(), чтобы обойти слой буферизации вывода PHP.
Пример:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
for ($i = 0; $i < 10; $i++) {
echo "id: $i\n";
echo "data: " . json_encode(['counter' => $i]) . "\n\n";
oxphp_stream_flush();
oxphp_sleep(1.0); // use oxphp_sleep instead of sleep — does not block the worker in fiber mode
}oxphp_sleep()
oxphp_sleep(float $seconds): voidПриостанавливает выполнение на указанную длительность. Внутри обработчика режима воркеров, выполняющегося в файбере, этот вызов кооперативен — он приостанавливает текущий файбер, чтобы во время ожидания могли обрабатываться другие запросы. Вне файбера он откатывается к стандартному блокирующему usleep().
Параметры:
$seconds— длительность приостановки в секундах. Допускаются дробные значения (например,0.5для 500 миллисекунд). Значения0или меньше возвращают управление немедленно.
Возвращает: void
Пример:
<?php
oxphp_worker(function () {
// In worker mode with fiber multiplexing:
// this suspends the fiber rather than blocking the thread
oxphp_sleep(1.0);
echo json_encode(['done' => true]);
});oxphp_usleep()
oxphp_usleep(int $microseconds): voidПриостанавливает выполнение на указанное число микросекунд. Как и oxphp_sleep(), этот вызов кооперативен внутри файбера и в противном случае откатывается к блокирующему usleep().
Параметры:
$microseconds— длительность приостановки в микросекундах. Значения0или меньше возвращают управление немедленно.
Возвращает: void
Пример:
<?php
oxphp_worker(function () {
// Poll for a condition every 100ms without blocking other requests
while (!$condition_met()) {
oxphp_usleep(100_000);
}
echo "ready";
});oxphp_async()
oxphp_async(Closure $closure, mixed ...$args): intОтправляет замыкание на выполнение в выделенном асинхронном потоке воркера и немедленно возвращает идентификатор промиса. Вызывающий код продолжает выполнение, не дожидаясь завершения замыкания. Используйте oxphp_async_await() для получения результата.
Параметры:
$closure— пользовательскоеClosureдля выполнения в асинхронном потоке воркера...$args— аргументы, передаваемые замыканию. Принимаются скалярные значения (null,bool,int,float,string), массивы из них и экземплярыOxPHP\Shared\*(единственные объекты, которые могут пересекать границу потока). Ресурсы и любые объекты, не являющиесяShared, отклоняются.
Возвращает: целочисленный идентификатор промиса. Передайте его в oxphp_async_await(), oxphp_async_await_all(), oxphp_async_await_race() или oxphp_async_await_any().
Выбрасывает: OxPHP\Async\AsyncException в следующих случаях:
- Асинхронный пул отключён (
ASYNC_WORKERS=0) — сообщение: "Async pool is disabled. Set ASYNC_WORKERS > 0 to enable." - Замыкание не является пользовательским
- Асинхронный пул заполнен (все слоты очереди заняты)
- Аргументы или переменные
useсодержат объекты или ресурсы
Переменные, захваченные через use в замыкании, подчиняются тем же ограничениям — объекты и ресурсы отклоняются.
Пример:
<?php
// Dispatch two independent tasks concurrently
$p1 = oxphp_async(function () {
return fetch_from_api('/users');
});
$p2 = oxphp_async(function () {
return fetch_from_api('/posts');
});
// Retrieve both results
$users = oxphp_async_await($p1);
$posts = oxphp_async_await($p2);oxphp_async_await()
oxphp_async_await(int $promise_id, float $timeout = 0.0): mixedБлокирует выполнение, пока указанный асинхронный промис не завершится, и возвращает его результат. Внутри файбера режима воркеров этот вызов кооперативно приостанавливает текущий файбер, а не блокирует поток.
Параметры:
$promise_id— идентификатор промиса, возвращённыйoxphp_async()$timeout— максимальное время ожидания в секундах.0.0означает ждать бесконечно. По умолчанию:0.0
Возвращает: возвращаемое значение асинхронного замыкания.
Выбрасывает:
OxPHP\Async\AsyncException, если асинхронный пул отключён (ASYNC_WORKERS=0) или если асинхронная задача выбросила исключениеOxPHP\Async\TimeoutException, если превышен$timeout
Пример:
<?php
$promise = oxphp_async(function (int $n) {
return array_sum(range(1, $n));
}, 1_000_000);
$result = oxphp_async_await($promise);
echo $result; // 500000500000
// With timeout
try {
$result = oxphp_async_await($promise, 5.0);
} catch (\OxPHP\Async\TimeoutException $e) {
echo "Task took too long";
}oxphp_async_await_all()
oxphp_async_await_all(array $promise_ids, float $timeout = 0.0): arrayОжидает все промисы в массиве и возвращает ассоциативный массив, сопоставляющий каждый идентификатор промиса с его результатом. Промисы ожидаются в порядке следования в массиве.
Параметры:
$promise_ids— массив целочисленных идентификаторов промисов, возвращённыхoxphp_async()$timeout— максимальное время ожидания на каждый промис в секундах.0.0означает ждать бесконечно. По умолчанию:0.0
Возвращает: ассоциативный массив, где каждый ключ — это идентификатор промиса (целое число), а каждое значение — результат этого промиса.
Выбрасывает:
OxPHP\Async\AsyncException, если асинхронный пул отключён (ASYNC_WORKERS=0) или если любой промис завершается с ошибкойOxPHP\Async\TimeoutException, если любой промис превышает$timeout
Пример:
<?php
$promises = [
oxphp_async(fn() => slow_query('users')),
oxphp_async(fn() => slow_query('orders')),
oxphp_async(fn() => slow_query('products')),
];
$results = oxphp_async_await_all($promises);
foreach ($results as $promiseId => $result) {
// process $result
}oxphp_async_await_race()
oxphp_async_await_race(array $promise_ids, float $timeout = 0.0): arrayУстраивает гонку между несколькими промисами и возвращает первый разрешившийся, независимо от того, выполнился он или был отклонён. Остальные промисы не отменяются — они продолжают выполняться и остаются доступными для ожидания через oxphp_async_await(). Это аналог JavaScript Promise.race.
Параметры:
$promise_ids— массив как минимум из одного целочисленного идентификатора промиса, возвращённогоoxphp_async(). Не должен быть пустым.$timeout— максимальное время ожидания разрешения любого промиса в секундах.0.0означает ждать бесконечно. По умолчанию:0.0
Возвращает: ассоциативный массив с двумя ключами:
id(int) — идентификатор промиса-победителяvalue(mixed) — возвращаемое значение победившего промиса
Выбрасывает:
OxPHP\Async\AsyncException, если асинхронный пул отключён (ASYNC_WORKERS=0) или если победивший промис был отклонёнOxPHP\Async\TimeoutException, если ни один промис не разрешился в течение$timeout
Пример:
<?php
// Try two mirror endpoints; use whichever responds first
$p1 = oxphp_async(fn() => fetch('https://mirror-1.example.com/data'));
$p2 = oxphp_async(fn() => fetch('https://mirror-2.example.com/data'));
$winner = oxphp_async_await_race([$p1, $p2], timeout: 10.0);
echo "Mirror {$winner['id']} won: " . json_encode($winner['value']);oxphp_async_await_any()
oxphp_async_await_any(array $promise_ids, float $timeout = 0.0): arrayВозвращает управление, как только один промис ВЫПОЛНЯЕТСЯ. Отклонения накапливаются и становятся наблюдаемыми только в том случае, если отклоняются все промисы. Это аналог JavaScript Promise.any — полезен для паттернов резервирования / избыточности, когда вам подходит любой работающий источник.
Параметры:
$promise_ids— массив как минимум из одного целочисленного идентификатора промиса, возвращённогоoxphp_async(). Не должен быть пустым.$timeout— максимальное время ожидания первого выполнения в секундах.0.0означает ждать бесконечно. По умолчанию:0.0
Возвращает: ассоциативный массив с двумя ключами:
id(int) — идентификатор первого выполнившегося промисаvalue(mixed) — возвращаемое значение победившего промиса
Выбрасывает:
OxPHP\Async\AsyncException, если асинхронный пул отключён (ASYNC_WORKERS=0)OxPHP\Async\AggregateAsyncException, если отклонён каждый промис. Исключение переносит все ошибки черезgetErrors()(позиционные, с ключами 0..N-1),getErrorMap()(с ключами по id) иgetPromiseIds().OxPHP\Async\TimeoutException, если ни один промис не выполнился в течение$timeout.getPartialErrors()перечисляет промисы, которые уже были отклонены до дедлайна;getCancelledPromiseIds()перечисляет те, что не разрешились и поэтому были отменены. Для них устанавливается флаг отмены, а их приёмники сбрасываются — передача любого из этих идентификаторов вoxphp_async_await*()впоследствии выбрасывает"unknown or already-awaited promise id". Этот список — журнал аудита, а не очередь возобновляемой работы.
Поведение:
- Промисы, которые всё ещё были в ожидании в момент победы, остаются доступными для ожидания по отдельности через
oxphp_async_await(). - Промисы, которые уже были отклонены до победителя, — нет: их результаты были потреблены при накоплении в качестве кандидатов-ошибок.
Пример:
<?php
$mirror_a = oxphp_async(fn() => fetch('https://mirror-a.example.com/data'));
$mirror_b = oxphp_async(fn() => fetch('https://mirror-b.example.com/data'));
$mirror_c = oxphp_async(fn() => fetch('https://mirror-c.example.com/data'));
try {
$winner = oxphp_async_await_any([$mirror_a, $mirror_b, $mirror_c], 5.0);
echo "Mirror {$winner['id']} responded: " . json_encode($winner['value']);
} catch (\OxPHP\Async\AggregateAsyncException $e) {
// every mirror rejected
foreach ($e->getErrorMap() as $promise_id => $err) {
error_log("mirror {$promise_id}: " . $err->getMessage());
}
} catch (\OxPHP\Async\TimeoutException $e) {
// deadline elapsed before any mirror fulfilled
$partial = $e->getPartialErrors();
$cancelled = $e->getCancelledPromiseIds();
}oxphp_register_decorator()
oxphp_register_decorator(string $class): boolРегистрирует PHP-класс как декоратор, оборачивающий вызовы функций и методов. Класс должен реализовывать OxPHP\Decorator\AttributeInterface. После регистрации OxPHP вызывает хуки декоратора before() и after() вокруг каждого вызова функции или метода, который соответствует целям #[Attribute] декоратора.
Параметры:
$class— полное имя класса декоратора для регистрации
Возвращает: true при успехе, false, если класс не существует или не реализует OxPHP\Decorator\AttributeInterface.
Пример:
<?php
use OxPHP\Decorator\AttributeInterface;
use OxPHP\Decorator\Context;
#[\Attribute(\Attribute::TARGET_METHOD)]
class LogDecorator implements AttributeInterface
{
public function before(Context $ctx): void
{
error_log("Calling {$ctx->target} (request {$ctx->requestId})");
}
public function after(Context $ctx): void
{
error_log("Finished {$ctx->target}");
}
}
// Register once at bootstrap (or worker startup)
oxphp_register_decorator(LogDecorator::class);oxphp_apm_trace()
oxphp_apm_trace(string $name, callable $callback, ?array $attributes = null): voidВыполняет колбэк внутри именованного спана. Спан открывается перед выполнением колбэка и закрывается после его возврата. Зарезервировано для будущей расширенной интеграции колбэков.
Параметры:
$name— имя спана$callback— вызываемый объект для выполнения внутри спана$attributes— необязательный ассоциативный массив строковых пар ключ-значение атрибутов
Возвращает: void
oxphp_apm_start()
oxphp_apm_start(string $name, ?array $attributes = null): intОткрывает новый спан и возвращает локальный идентификатор для последующих ссылок. Спан становится дочерним по отношению к текущему активному спану (или к корневому спану запроса, если ни один спан не активен). Используйте oxphp_apm_end(), чтобы закрыть его.
Параметры:
$name— имя спана (например,"cache.warm","payment.process")$attributes— необязательный ассоциативный массив строковых пар ключ-значение атрибутов, устанавливаемых на спан при создании
Возвращает: целочисленный локальный идентификатор спана. Передайте его в oxphp_apm_end(), oxphp_apm_attribute() или другие функции, принимающие $span_id. Возвращает 0, когда APM отключён.
Пример:
<?php
$spanId = oxphp_apm_start('order.validate', [
'order.type' => 'subscription',
]);
validateOrder($order);
oxphp_apm_end($spanId);oxphp_apm_end()
oxphp_apm_end(int $span_id): voidЗакрывает спан, открытый функцией oxphp_apm_start(). Записывается время завершения спана, и он перемещается из активного стека в список завершённых, готовый к экспорту.
Параметры:
$span_id— локальный идентификатор спана, возвращённыйoxphp_apm_start()
Возвращает: void
Всегда закрывайте спаны в обратном порядке. Если вы открыли спан A, затем спан B, закройте B перед A. Незакрытые спаны автоматически закрываются в конце запроса и помечаются oxphp.span.leaked=true.
oxphp_apm_attribute()
oxphp_apm_attribute(string $key, mixed $value, ?int $span_id = null): voidУстанавливает атрибут ключ-значение на спане. Значения преобразуются в строки. Если $span_id не указан, атрибут добавляется к текущему активному спану.
Параметры:
$key— ключ атрибута (например,"user.id","cache.hit")$value— значение атрибута (string, int, float, bool или null -- преобразуется в строку)$span_id— необязательный локальный идентификатор спана. Если опущен, нацеливается на текущий спан
Возвращает: void
Пример:
<?php
$spanId = oxphp_apm_start('db.query');
oxphp_apm_attribute('db.system', 'mysql');
oxphp_apm_attribute('db.statement', 'SELECT * FROM users WHERE id = ?');
oxphp_apm_attribute('db.row_count', $rowCount, $spanId);
oxphp_apm_end($spanId);oxphp_apm_event()
oxphp_apm_event(string $name, ?array $attributes = null, ?int $span_id = null): voidЗаписывает событие с меткой времени на спане. События полезны для логирования отдельных происшествий в течение жизни спана (например, промах кэша, попытка повтора, проверка авторизации).
Параметры:
$name— имя события (например,"cache.miss","retry")$attributes— необязательный ассоциативный массив строковых пар ключ-значение атрибутов события$span_id— необязательный локальный идентификатор спана. Если опущен, нацеливается на текущий спан
Возвращает: void
Пример:
<?php
$spanId = oxphp_apm_start('payment.process');
oxphp_apm_event('payment.authorized', [
'provider' => 'stripe',
'amount' => '49.99',
]);
oxphp_apm_end($spanId);oxphp_apm_error()
oxphp_apm_error(mixed $exception, ?int $span_id = null): voidПомечает статус спана как ошибку (код статуса 2). Используйте это для того, чтобы отметить спаны, где произошло исключение или сбой.
Параметры:
$exception— исключение или ошибка (используется для контекста; статус устанавливается независимо от типа)$span_id— необязательный локальный идентификатор спана. Если опущен, нацеливается на текущий спан
Возвращает: void
Пример:
<?php
$spanId = oxphp_apm_start('external.api');
try {
$result = callExternalApi();
} catch (\Throwable $e) {
oxphp_apm_error($e, $spanId);
throw $e;
} finally {
oxphp_apm_end($spanId);
}oxphp_apm_status()
oxphp_apm_status(int $code, ?string $description = null, ?int $span_id = null): voidУстанавливает код статуса и необязательное описание на спане.
Параметры:
$code— код статуса:0= Unset,1= Ok,2= Error$description— необязательное человекочитаемое описание статуса$span_id— необязательный локальный идентификатор спана. Если опущен, нацеливается на текущий спан
Возвращает: void
Пример:
<?php
$spanId = oxphp_apm_start('validation');
if ($valid) {
oxphp_apm_status(1, 'Validation passed', $spanId);
} else {
oxphp_apm_status(2, 'Invalid input: missing email', $spanId);
}
oxphp_apm_end($spanId);oxphp_apm_trace_id()
oxphp_apm_trace_id(): stringВозвращает W3C trace ID (32 шестнадцатеричных символа) для контекста трассировки текущего запроса. Это то же значение, что и $_SERVER['OXPHP_TRACE_ID'], доступное без суперглобальных переменных.
Возвращает: 32-символьную шестнадцатеричную строку trace ID. Возвращает пустую строку, когда APM отключён или контекст трассировки не активен.
Пример:
<?php
$traceId = oxphp_apm_trace_id();
error_log("Processing request in trace {$traceId}");oxphp_apm_span_id()
oxphp_apm_span_id(): stringВозвращает span ID (16 шестнадцатеричных символов) текущего активного спана. Если есть вложенные спаны, возвращается идентификатор самого внутреннего открытого спана.
Возвращает: 16-символьную шестнадцатеричную строку span ID. Возвращает пустую строку, когда ни один спан не активен.
oxphp_apm_header()
oxphp_apm_header(): stringВозвращает значение W3C-заголовка traceparent для текущего контекста спана. Используйте это для передачи контекста трассировки в нижестоящие HTTP-вызовы.
Возвращает: строку в формате 00-{trace_id}-{span_id}-01. Возвращает пустую строку, когда контекст трассировки не активен.
Пример:
<?php
$spanId = oxphp_apm_start('http.call');
$traceparent = oxphp_apm_header();
$response = file_get_contents('https://api.example.com/data', false,
stream_context_create([
'http' => [
'header' => "traceparent: {$traceparent}\r\n",
],
])
);
oxphp_apm_end($spanId);OxPHP\Profile\is_active()
OxPHP\Profile\is_active(): boolВозвращает true, когда захват профиля в данный момент активен для этого запроса — то есть профилировщик был запущен (заголовком, cookie, параметром строки запроса или частотой сэмплирования), а захват не был приостановлен через pause().
Полезно для защиты дорогостоящей инструментации, которая должна выполняться только при включённом профилировании.
Возвращает: bool.
Пример:
<?php
if (OxPHP\Profile\is_active()) {
OxPHP\Profile\mark('checkpoint.before_query');
}OxPHP\Profile\start()
OxPHP\Profile\start(): voidПрограммно включает захват профиля до конца текущего запроса, даже если ни один триггер не сработал на RINIT. Устанавливает режим профилирования в PROFILE_ALL и снимает флаг приостановки.
Если профиль уже был активен в другом режиме, этот вызов повышает его — любые спаны, уже собранные в более низком режиме, отбрасываются, чтобы захваченный профиль был внутренне согласованным. Используйте это, когда хотите включить в профилирование конкретный путь выполнения кода, не полагаясь на триггеры.
Возвращает: void.
Пример:
<?php
if ($request->header('x-debug') === 'on') {
OxPHP\Profile\start();
}OxPHP\Profile\stop()
OxPHP\Profile\stop(): voidОтключает дальнейший захват спанов для этого запроса. Уже открытые спаны закрываются естественным образом по мере того, как PHP возвращается из них, поэтому стек вызовов остаётся сбалансированным — прекращается лишь запись новых спанов.
Возвращает: void.
Пример:
<?php
OxPHP\Profile\start();
expensive_work();
OxPHP\Profile\stop();
non_profiled_work();OxPHP\Profile\pause()
OxPHP\Profile\pause(): voidМягкий вариант stop(). Эффект тот же (устанавливает флаг приостановки); различие в намерении — pause() сигнализирует, что захват возобновится позже через resume(), тогда как stop() — нет.
Возвращает: void.
OxPHP\Profile\resume()
OxPHP\Profile\resume(): voidСнимает флаг приостановки, установленный pause() или stop(). Сам режим профиля при этом не меняется — если он никогда не был включён, resume() не делает ничего наблюдаемого.
Возвращает: void.
Пример:
<?php
OxPHP\Profile\pause();
$secret = decrypt_payload($data);
OxPHP\Profile\resume();OxPHP\Profile\mark()
OxPHP\Profile\mark(string $label, ?array $attrs = null): voidПрикрепляет событие Mark к самому верхнему открытому спану, с необязательным набором атрибутов. Ничего не делает, когда нет открытого спана (например, профилирование не активно, или mark() вызвана на верхнем уровне запроса вне какого-либо инструментированного фрейма).
Ключи и значения атрибутов приводятся к строкам; нестроковые значения становятся пустой строкой.
Параметры:
$label— короткое человекочитаемое имя события (например,"cache.miss","db.slow_query")$attrs— необязательныйarray<string, scalar>пар ключ/значение, прикрепляемых к событию
Возвращает: void.
Пример:
<?php
function load_user(int $id): array {
$cached = $cache->get("user:$id");
if ($cached === null) {
OxPHP\Profile\mark('cache.miss', ['key' => "user:$id"]);
$cached = $db->fetchUser($id);
}
return $cached;
}OxPHP\Profile\metric()
OxPHP\Profile\metric(string $name, float $value): voidДобавляет атрибут metric.<name> к текущему открытому спану. Ничего не делает, когда нет открытого спана.
В отличие от mark() (которая создаёт отдельное событие), metric() записывает данные в набор атрибутов существующего спана — полезно для фиксации числовых наблюдений, привязанных к окружающей операции (число полученных строк, обработанных байтов, количество повторов).
Параметры:
$name— идентификатор метрики; будет сохранён какmetric.<name>$value— числовое значение (приводится кfloat)
Возвращает: void.
Пример:
<?php
function search(string $query): array {
$results = $index->search($query);
OxPHP\Profile\metric('result_count', count($results));
return $results;
}Классы и интерфейсы
Расширение oxphp_sapi регистрирует следующие классы:
HTTP
| Класс | Описание |
|---|---|
OxPHP\Http\Request |
Объект запроса, возвращаемый oxphp_http_request(). final — не может быть расширен. |
OxPHP\Http\Attributes |
Изменяемый контейнер атрибутов запроса (для middleware). final. |
OxPHP\Http\Session |
Объект сессии, доступный через $request->session(). final. |
OxPHP\Http\UploadedFile |
Объект загруженного файла из $request->files(). final. |
Декораторы
| Класс / интерфейс | Описание |
|---|---|
OxPHP\Decorator\AttributeInterface |
Интерфейс для декораторов. Требует методов before(Context $ctx) и after(Context $ctx). |
OxPHP\Decorator\Context |
Контекстный объект, передаваемый хукам декоратора. final. Публичные свойства: target, class, method, function, objectId, requestId, traceId. Методы: getParams(): array, getResult(): mixed, hasResult(): bool. Полный справочник см. в Декораторы. |
Трассировка
| Класс | Описание |
|---|---|
OxPHP\Apm\Trace |
Встроенный атрибут для автоматического создания спанов. Применяется к функциям или методам. |
Async
| Класс | Описание |
|---|---|
OxPHP\Async\BorrowedProxy |
Прокси-объект для одолженных значений между потоками. |
Исключения
Все исключения, регистрируемые расширением:
| Исключение | Расширяет | Когда выбрасывается |
|---|---|---|
OxPHP\Async\AsyncException |
\Exception |
Ошибка в асинхронной задаче (oxphp_async_await()) или недопустимые аргументы в oxphp_async() |
OxPHP\Async\TimeoutException |
OxPHP\Async\AsyncException |
Превышен таймаут в любой из oxphp_async_await(), oxphp_async_await_all(), oxphp_async_await_race() или oxphp_async_await_any(). Для таймаутов oxphp_async_await_any() заполняются аксессоры getPartialErrors(): array<int, \Throwable> и getCancelledPromiseIds(): list<int>; для остальных мест вызова оба возвращают []. |
OxPHP\Async\AggregateAsyncException |
OxPHP\Async\AsyncException |
Выбрасывается oxphp_async_await_any(), когда отклонён каждый промис. Методы: getErrors(): list<\Throwable> (позиционные, с ключами 0..N-1 по позиции во входных данных), getErrorMap(): array<int, \Throwable> (с ключами по id промиса), getPromiseIds(): list<int> (входные id промисов по порядку). |
OxPHP\Async\BorrowException |
\Exception |
Ошибка при одалживании значения между потоками |
OxPHP\Http\Exception\NoActiveRequestException |
\RuntimeException |
Вызов oxphp_http_request() вне активного запроса |
OxPHP\Http\Exception\AsyncContextException |
NoActiveRequestException |
Вызов oxphp_http_request() внутри колбэка oxphp_async() |
OxPHP\Http\Exception\WorkerIdleException |
NoActiveRequestException |
Вызов oxphp_http_request() в режиме воркеров между запросами |
OxPHP\Decorator\RejectedException |
\Exception |
Декоратор отклонил вызов функции/метода |
Проверка расширения
Вы можете проверить, что расширение OxPHP загружено, и просмотреть все зарегистрированные функции:
<?php
if (extension_loaded('oxphp_sapi')) {
echo "OxPHP extension is loaded\n";
}
$functions = get_extension_funcs('oxphp_sapi');
print_r($functions);
// Array
// (
// [0] => oxphp_http_request
// [1] => oxphp_superglobals_enabled
// [2] => oxphp_request_id
// [3] => oxphp_worker_id
// [4] => oxphp_server_info
// [5] => oxphp_finish_request
// [6] => oxphp_is_worker
// [7] => oxphp_is_streaming
// [8] => oxphp_stream_flush
// [9] => oxphp_sleep
// [10] => oxphp_usleep
// [11] => oxphp_worker
// [12] => oxphp_register_decorator
// [13] => oxphp_async
// [14] => oxphp_async_await
// [15] => oxphp_async_await_all
// [16] => oxphp_async_await_race
// [17] => oxphp_async_await_any
// [18] => oxphp_apm_trace
// [19] => oxphp_apm_start
// [20] => oxphp_apm_end
// [21] => oxphp_apm_attribute
// [22] => oxphp_apm_event
// [23] => oxphp_apm_error
// [24] => oxphp_apm_status
// [25] => oxphp_apm_trace_id
// [26] => oxphp_apm_span_id
// [27] => oxphp_apm_header
// )Основные функции SAPI (вплоть до oxphp_register_decorator) идут первыми; семейства oxphp_async_* и oxphp_apm_* — а также SDK OxPHP\Profile\*, когда профилировщик встроен, — добавляются их плагинами во время инициализации модуля. Считайте этот список иллюстративным: точный набор и порядок зависят от того, какие плагины скомпилированы в сборку.
Совместимость с PHP-FPM
Если ваш код должен работать и на OxPHP, и на PHP-FPM, используйте обёртки-запасные варианты:
<?php
function finish_request(): bool
{
if (function_exists('oxphp_finish_request')) {
return oxphp_finish_request();
}
if (function_exists('fastcgi_finish_request')) {
return fastcgi_finish_request();
}
return false;
}
// Worker-aware bootstrap
if (function_exists('oxphp_is_worker') && oxphp_is_worker()) {
// OxPHP worker mode
} else {
// PHP-FPM or OxPHP traditional mode
}Семейство функций oxphp_async() всегда зарегистрировано в OxPHP, поэтому function_exists('oxphp_async') возвращает true, даже когда ASYNC_WORKERS=0. Когда пул отключён, вызов любой асинхронной функции выбрасывает OxPHP\Async\AsyncException. Если ваш код должен обрабатывать обе конфигурации, перехватывайте исключение, а не проверяйте function_exists().
См. также
- HTTP Request API -- объектно-ориентированный доступ к данным запроса через
oxphp_http_request() - Режим воркеров -- постоянный цикл воркера и жизненный цикл запроса
- Server-Sent Events -- потоковая передача в реальном времени с
oxphp_stream_flush() - Ранний ответ -- фоновая обработка с
oxphp_finish_request() - Суперглобальные переменные -- как OxPHP заполняет
$_SERVER,$_GET,$_POSTи другие суперглобальные переменные - Распределённая трассировка и APM -- W3C Trace Context, экспорт OTel и SDK
oxphp_apm_*() - Справочник по конфигурации --
WORKER_MODE_ENABLED,ENTRY_FILE,PHP_WORKERSи другие переменные окружения