PHP-функции

OxPHP регистрирует свои функции через расширение oxphp_sapi, которое автоматически загружается для каждого PHP-скрипта, выполняемого сервером. Директива extension= и ручная загрузка не требуются. Все перечисленные здесь функции доступны с первой строки вашего PHP-кода.

Оглавление

oxphp_http_request()

php
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
<?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()

php
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
<?php if (oxphp_superglobals_enabled()) { $query = $_GET['page'] ?? 1; } else { $query = oxphp_http_request()->query('page', 1); }

oxphp_request_id()

php
oxphp_request_id(): string

Возвращает уникальный идентификатор текущего запроса. Это то же значение, что отправляется в заголовке ответа X-Request-ID. Если клиент присылает заголовок X-Request-ID, OxPHP пропускает его без изменений вместо генерации нового.

Возвращает: 20-символьную шестнадцатеричную строку, когда идентификатор генерирует OxPHP (например, "67890abc12341a2b0042"). Когда клиент присылает заголовок X-Request-ID, это значение возвращается как есть (1–64 символа, буквы и цифры плюс -, _, .).

Пример:

php
<?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()

php
oxphp_worker_id(): int

Возвращает индекс (отсчёт с нуля) PHP-потока воркера, обрабатывающего текущий запрос. Индексы воркеров находятся в диапазоне от 0 до PHP_WORKERS - 1.

Возвращает: целое число, идентифицирующее текущий поток воркера.

Пример:

php
<?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()

php
oxphp_server_info(): array

Возвращает ассоциативный массив с метаданными сервера и запроса.

Возвращает: массив со следующими ключами:

Ключ Тип Описание
version string Версия сервера (например, "0.10.0")
worker_id int То же значение, что и oxphp_worker_id()
request_time float Unix-метка времени с микросекундной точностью, когда начался запрос
worker_mode bool Работает ли текущий процесс в режиме воркеров

Пример:

php
<?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()

php
oxphp_finish_request(): bool

Сбрасывает ответ клиенту и продолжает выполнение PHP в фоне. Клиент немедленно получает полный HTTP-ответ; скрипт продолжает работать, пока не завершится естественным образом. Это аналог fastcgi_finish_request() из PHP-FPM в OxPHP.

Возвращает: true при успехе, false, если функция уже была вызвана для этого запроса.

Note

PHP-поток воркера остаётся занятым, пока скрипт не завершится. Держите фоновую работу короткой или выносите тяжёлую обработку в очередь.

Пример:

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()

php
oxphp_is_worker(): bool

Возвращает, работает ли сервер в режиме воркеров. Режим воркеров активируется, когда WORKER_MODE_ENABLED=true.

Возвращает: true, если сервер работает в режиме воркеров, false — в традиционном режиме.

Пример:

php
<?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()

php
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()
Note

oxphp_worker() работает только в режиме воркеров (WORKER_MODE_ENABLED=true). В традиционном режиме она пишет предупреждение в лог и возвращает false.

Пример:

worker.php
<?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()

php
oxphp_is_streaming(): bool

Возвращает, находится ли текущий запрос в потоковом режиме. Потоковый режим активируется при первом вызове oxphp_stream_flush() или автоматически, когда PHP устанавливает Content-Type: text/event-stream.

Возвращает: true, если потоковый режим активен, иначе false.

Пример:

php
<?php if (oxphp_is_streaming()) { echo "data: " . json_encode($event) . "\n\n"; oxphp_stream_flush(); } else { echo json_encode($allData); }

oxphp_stream_flush()

php
oxphp_stream_flush(): bool

Активирует потоковый режим и сбрасывает любой буферизованный вывод клиенту в виде HTTP-чанка. При первом вызове HTTP-заголовки отправляются немедленно и начинается потоковая передача. Каждый последующий вызов сбрасывает вывод, записанный со времени предыдущего сброса.

Возвращает: true при успехе, false, если oxphp_finish_request() уже была вызвана.

Note

Потоковый режим также активируется автоматически, когда PHP устанавливает Content-Type: text/event-stream. В этом случае можно использовать встроенную функцию PHP flush(), но сначала вызовите ob_end_flush(), чтобы обойти слой буферизации вывода PHP.

Пример:

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()

php
oxphp_sleep(float $seconds): void

Приостанавливает выполнение на указанную длительность. Внутри обработчика режима воркеров, выполняющегося в файбере, этот вызов кооперативен — он приостанавливает текущий файбер, чтобы во время ожидания могли обрабатываться другие запросы. Вне файбера он откатывается к стандартному блокирующему usleep().

Параметры:

  • $seconds — длительность приостановки в секундах. Допускаются дробные значения (например, 0.5 для 500 миллисекунд). Значения 0 или меньше возвращают управление немедленно.

Возвращает: void

Пример:

php
<?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()

php
oxphp_usleep(int $microseconds): void

Приостанавливает выполнение на указанное число микросекунд. Как и oxphp_sleep(), этот вызов кооперативен внутри файбера и в противном случае откатывается к блокирующему usleep().

Параметры:

  • $microseconds — длительность приостановки в микросекундах. Значения 0 или меньше возвращают управление немедленно.

Возвращает: void

Пример:

php
<?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()

php
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 содержат объекты или ресурсы
Note

Переменные, захваченные через use в замыкании, подчиняются тем же ограничениям — объекты и ресурсы отклоняются.

Пример:

php
<?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()

php
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
<?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()

php
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
<?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()

php
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
<?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()

php
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
<?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()

php
oxphp_register_decorator(string $class): bool

Регистрирует PHP-класс как декоратор, оборачивающий вызовы функций и методов. Класс должен реализовывать OxPHP\Decorator\AttributeInterface. После регистрации OxPHP вызывает хуки декоратора before() и after() вокруг каждого вызова функции или метода, который соответствует целям #[Attribute] декоратора.

Параметры:

  • $class — полное имя класса декоратора для регистрации

Возвращает: true при успехе, false, если класс не существует или не реализует OxPHP\Decorator\AttributeInterface.

Пример:

php
<?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()

php
oxphp_apm_trace(string $name, callable $callback, ?array $attributes = null): void

Выполняет колбэк внутри именованного спана. Спан открывается перед выполнением колбэка и закрывается после его возврата. Зарезервировано для будущей расширенной интеграции колбэков.

Параметры:

  • $name — имя спана
  • $callback — вызываемый объект для выполнения внутри спана
  • $attributes — необязательный ассоциативный массив строковых пар ключ-значение атрибутов

Возвращает: void

oxphp_apm_start()

php
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
<?php $spanId = oxphp_apm_start('order.validate', [ 'order.type' => 'subscription', ]); validateOrder($order); oxphp_apm_end($spanId);

oxphp_apm_end()

php
oxphp_apm_end(int $span_id): void

Закрывает спан, открытый функцией oxphp_apm_start(). Записывается время завершения спана, и он перемещается из активного стека в список завершённых, готовый к экспорту.

Параметры:

  • $span_id — локальный идентификатор спана, возвращённый oxphp_apm_start()

Возвращает: void

Note

Всегда закрывайте спаны в обратном порядке. Если вы открыли спан A, затем спан B, закройте B перед A. Незакрытые спаны автоматически закрываются в конце запроса и помечаются oxphp.span.leaked=true.

oxphp_apm_attribute()

php
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
<?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()

php
oxphp_apm_event(string $name, ?array $attributes = null, ?int $span_id = null): void

Записывает событие с меткой времени на спане. События полезны для логирования отдельных происшествий в течение жизни спана (например, промах кэша, попытка повтора, проверка авторизации).

Параметры:

  • $name — имя события (например, "cache.miss", "retry")
  • $attributes — необязательный ассоциативный массив строковых пар ключ-значение атрибутов события
  • $span_id — необязательный локальный идентификатор спана. Если опущен, нацеливается на текущий спан

Возвращает: void

Пример:

php
<?php $spanId = oxphp_apm_start('payment.process'); oxphp_apm_event('payment.authorized', [ 'provider' => 'stripe', 'amount' => '49.99', ]); oxphp_apm_end($spanId);

oxphp_apm_error()

php
oxphp_apm_error(mixed $exception, ?int $span_id = null): void

Помечает статус спана как ошибку (код статуса 2). Используйте это для того, чтобы отметить спаны, где произошло исключение или сбой.

Параметры:

  • $exception — исключение или ошибка (используется для контекста; статус устанавливается независимо от типа)
  • $span_id — необязательный локальный идентификатор спана. Если опущен, нацеливается на текущий спан

Возвращает: void

Пример:

php
<?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()

php
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
<?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()

php
oxphp_apm_trace_id(): string

Возвращает W3C trace ID (32 шестнадцатеричных символа) для контекста трассировки текущего запроса. Это то же значение, что и $_SERVER['OXPHP_TRACE_ID'], доступное без суперглобальных переменных.

Возвращает: 32-символьную шестнадцатеричную строку trace ID. Возвращает пустую строку, когда APM отключён или контекст трассировки не активен.

Пример:

php
<?php $traceId = oxphp_apm_trace_id(); error_log("Processing request in trace {$traceId}");

oxphp_apm_span_id()

php
oxphp_apm_span_id(): string

Возвращает span ID (16 шестнадцатеричных символов) текущего активного спана. Если есть вложенные спаны, возвращается идентификатор самого внутреннего открытого спана.

Возвращает: 16-символьную шестнадцатеричную строку span ID. Возвращает пустую строку, когда ни один спан не активен.

oxphp_apm_header()

php
oxphp_apm_header(): string

Возвращает значение W3C-заголовка traceparent для текущего контекста спана. Используйте это для передачи контекста трассировки в нижестоящие HTTP-вызовы.

Возвращает: строку в формате 00-{trace_id}-{span_id}-01. Возвращает пустую строку, когда контекст трассировки не активен.

Пример:

php
<?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()

php
OxPHP\Profile\is_active(): bool

Возвращает true, когда захват профиля в данный момент активен для этого запроса — то есть профилировщик был запущен (заголовком, cookie, параметром строки запроса или частотой сэмплирования), а захват не был приостановлен через pause().

Полезно для защиты дорогостоящей инструментации, которая должна выполняться только при включённом профилировании.

Возвращает: bool.

Пример:

php
<?php if (OxPHP\Profile\is_active()) { OxPHP\Profile\mark('checkpoint.before_query'); }

OxPHP\Profile\start()

php
OxPHP\Profile\start(): void

Программно включает захват профиля до конца текущего запроса, даже если ни один триггер не сработал на RINIT. Устанавливает режим профилирования в PROFILE_ALL и снимает флаг приостановки.

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

Возвращает: void.

Пример:

php
<?php if ($request->header('x-debug') === 'on') { OxPHP\Profile\start(); }

OxPHP\Profile\stop()

php
OxPHP\Profile\stop(): void

Отключает дальнейший захват спанов для этого запроса. Уже открытые спаны закрываются естественным образом по мере того, как PHP возвращается из них, поэтому стек вызовов остаётся сбалансированным — прекращается лишь запись новых спанов.

Возвращает: void.

Пример:

php
<?php OxPHP\Profile\start(); expensive_work(); OxPHP\Profile\stop(); non_profiled_work();

OxPHP\Profile\pause()

php
OxPHP\Profile\pause(): void

Мягкий вариант stop(). Эффект тот же (устанавливает флаг приостановки); различие в намерении — pause() сигнализирует, что захват возобновится позже через resume(), тогда как stop() — нет.

Возвращает: void.

OxPHP\Profile\resume()

php
OxPHP\Profile\resume(): void

Снимает флаг приостановки, установленный pause() или stop(). Сам режим профиля при этом не меняется — если он никогда не был включён, resume() не делает ничего наблюдаемого.

Возвращает: void.

Пример:

php
<?php OxPHP\Profile\pause(); $secret = decrypt_payload($data); OxPHP\Profile\resume();

OxPHP\Profile\mark()

php
OxPHP\Profile\mark(string $label, ?array $attrs = null): void

Прикрепляет событие Mark к самому верхнему открытому спану, с необязательным набором атрибутов. Ничего не делает, когда нет открытого спана (например, профилирование не активно, или mark() вызвана на верхнем уровне запроса вне какого-либо инструментированного фрейма).

Ключи и значения атрибутов приводятся к строкам; нестроковые значения становятся пустой строкой.

Параметры:

  • $label — короткое человекочитаемое имя события (например, "cache.miss", "db.slow_query")
  • $attrs — необязательный array<string, scalar> пар ключ/значение, прикрепляемых к событию

Возвращает: void.

Пример:

php
<?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()

php
OxPHP\Profile\metric(string $name, float $value): void

Добавляет атрибут metric.<name> к текущему открытому спану. Ничего не делает, когда нет открытого спана.

В отличие от mark() (которая создаёт отдельное событие), metric() записывает данные в набор атрибутов существующего спана — полезно для фиксации числовых наблюдений, привязанных к окружающей операции (число полученных строк, обработанных байтов, количество повторов).

Параметры:

  • $name — идентификатор метрики; будет сохранён как metric.<name>
  • $value — числовое значение (приводится к float)

Возвращает: void.

Пример:

php
<?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
<?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 // )
Note

Основные функции SAPI (вплоть до oxphp_register_decorator) идут первыми; семейства oxphp_async_* и oxphp_apm_* — а также SDK OxPHP\Profile\*, когда профилировщик встроен, — добавляются их плагинами во время инициализации модуля. Считайте этот список иллюстративным: точный набор и порядок зависят от того, какие плагины скомпилированы в сборку.

Совместимость с PHP-FPM

Если ваш код должен работать и на OxPHP, и на PHP-FPM, используйте обёртки-запасные варианты:

php
<?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 }
Note

Семейство функций oxphp_async() всегда зарегистрировано в OxPHP, поэтому function_exists('oxphp_async') возвращает true, даже когда ASYNC_WORKERS=0. Когда пул отключён, вызов любой асинхронной функции выбрасывает OxPHP\Async\AsyncException. Если ваш код должен обрабатывать обе конфигурации, перехватывайте исключение, а не проверяйте function_exists().

См. также

code