Funkcje PHP
OxPHP rejestruje swoje funkcje poprzez rozszerzenie oxphp_sapi, które ładuje się automatycznie dla każdego skryptu PHP wykonywanego przez serwer. Nie jest wymagana żadna dyrektywa extension= ani ręczne ładowanie. Każda funkcja wymieniona tutaj jest dostępna od pierwszej linijki Twojego kodu PHP.
Spis treści
- 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()
- Klasy i interfejsy
- Wyjątki
oxphp_http_request()
oxphp_http_request(): \OxPHP\Http\RequestZwraca obiekt żądania dla bieżącego żądania HTTP. Obiekt zapewnia typowany dostęp do metody HTTP, URI, parametrów zapytania, sparsowanego ciała, nagłówków, ciasteczek, przesłanych plików, adresu IP klienta oraz pomiaru czasu żądania.
Zwraca: Instancję \OxPHP\Http\Request opartą na danych żądania w bieżącym wątku worker PHP.
Rzuca: Wyjątek z przestrzeni nazw OxPHP\Http\Exception, gdy funkcja zostanie wywołana poza aktywnym żądaniem:
| Wyjątek | Sytuacja |
|---|---|
\OxPHP\Http\Exception\WorkerIdleException |
Tryb worker, pomiędzy żądaniami |
\OxPHP\Http\Exception\AsyncContextException |
Wewnątrz callbacku oxphp_async() |
\OxPHP\Http\Exception\NoActiveRequestException |
Każdy inny kontekst bez aktywnego żądania |
W normalnym kodzie obsługującym żądania obsługa wyjątków nie jest wymagana.
Przykład:
<?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');Pełną dokumentację interfejsu znajdziesz w dokumentacji HTTP Request API.
oxphp_superglobals_enabled()
oxphp_superglobals_enabled(): boolZwraca informację o tym, czy dla tej instancji serwera włączone jest wypełnianie superglobalnych. Wartość odzwierciedla zmienną środowiskową SUPERGLOBALS_ENABLED i nie zmienia się przez cały czas życia serwera.
Gdy wynosi false, $_GET, $_POST, $_COOKIE, $_FILES i $_SERVER są pustymi tablicami. Nie ma to wpływu na HTTP Object API (oxphp_http_request()), php://input ani funkcje sesji PHP.
Zwraca: true, gdy SUPERGLOBALS_ENABLED ma wartość true (domyślnie), w przeciwnym razie false.
Przykład:
<?php
if (oxphp_superglobals_enabled()) {
$query = $_GET['page'] ?? 1;
} else {
$query = oxphp_http_request()->query('page', 1);
}oxphp_request_id()
oxphp_request_id(): stringZwraca unikalny identyfikator bieżącego żądania. Jest to ta sama wartość, która jest wysyłana w nagłówku odpowiedzi X-Request-ID. Jeśli klient wyśle nagłówek X-Request-ID, OxPHP przekazuje go dalej bez zmian, zamiast generować nowy.
Zwraca: 20-znakowy ciąg szesnastkowy, gdy OxPHP generuje ID (np. "67890abc12341a2b0042"). Gdy klient wyśle nagłówek X-Request-ID, wartość ta jest zwracana bez zmian (1–64 znaki, alfanumeryczne plus -, _, .).
Przykład:
<?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(): intZwraca liczony od zera indeks wątku worker PHP obsługującego bieżące żądanie. Indeksy workerów mieszczą się w zakresie od 0 do PHP_WORKERS - 1.
Zwraca: Liczbę całkowitą identyfikującą bieżący wątek worker.
Przykład:
<?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(): arrayZwraca tablicę asocjacyjną z metadanymi serwera i żądania.
Zwraca: Tablicę z następującymi kluczami:
| Klucz | Typ | Opis |
|---|---|---|
version |
string |
Wersja serwera (np. "0.10.0") |
worker_id |
int |
Ta sama wartość co oxphp_worker_id() |
request_time |
float |
Znacznik czasu Unix z dokładnością do mikrosekund określający moment rozpoczęcia żądania |
worker_mode |
bool |
Czy bieżący proces działa w trybie worker |
Przykład:
<?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(): boolWypycha odpowiedź do klienta i kontynuuje wykonywanie PHP w tle. Klient otrzymuje kompletną odpowiedź HTTP natychmiast; skrypt działa dalej, aż zakończy się w sposób naturalny. Jest to odpowiednik fastcgi_finish_request() z PHP-FPM w OxPHP.
Zwraca: true w przypadku sukcesu, false, jeśli funkcja została już wywołana dla tego żądania.
Wątek worker PHP pozostaje zajęty, dopóki skrypt się nie zakończy. Zadbaj o to, aby praca w tle była krótka, lub przenieś ciężkie przetwarzanie do kolejki.
Przykład:
<?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(): boolZwraca informację o tym, czy serwer działa w trybie worker. Tryb worker aktywuje się, gdy WORKER_MODE_ENABLED=true.
Zwraca: true, jeśli działa w trybie worker, false w trybie tradycyjnym.
Przykład:
<?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): boolWchodzi do trwałej pętli trybu worker. OxPHP wywołuje $handler raz dla każdego przychodzącego żądania HTTP. Pomiędzy żądaniami miękki reset czyści stan powiązany z pojedynczym żądaniem — bufory wyjściowe, nagłówki i superglobalne — bez niszczenia sterty PHP, dzięki czemu wszelkie zmienne zadeklarowane poza handlerem zachowują trwałość między żądaniami.
Parametry:
$handler— Wywoływany raz na żądanie. Handler nie otrzymuje żadnych argumentów. Aby uzyskać dostęp do danych żądania, użyj wewnątrz handlera superglobalnych ($_SERVER,$_GET,$_POSTitd.) luboxphp_http_request().
Zwraca: true przy łagodnym zamknięciu, false, jeśli nie działa w trybie worker.
Pętla worker kończy działanie, gdy zostanie spełniony którykolwiek z poniższych warunków:
- Serwer łagodnie się zamyka
- Handler zgłosi 3 kolejne nieprzechwycone wyjątki lub błędy krytyczne
- Worker przekroczy
WORKER_MAX_MEMORY_MIB - Aplikacja wywoła
Worker::scheduleExit()
oxphp_worker() działa wyłącznie w trybie worker (WORKER_MODE_ENABLED=true). W trybie tradycyjnym zapisuje ostrzeżenie do logu i zwraca false.
Przykład:
<?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(): boolZwraca informację o tym, czy bieżące żądanie działa w trybie strumieniowania. Tryb strumieniowania aktywuje się przy pierwszym wywołaniu oxphp_stream_flush() lub automatycznie, gdy PHP ustawi Content-Type: text/event-stream.
Zwraca: true, jeśli tryb strumieniowania jest aktywny, w przeciwnym razie false.
Przykład:
<?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(): boolAktywuje tryb strumieniowania i wypycha wszelkie zbuforowane dane wyjściowe do klienta jako fragment (chunk) HTTP. Przy pierwszym wywołaniu nagłówki HTTP są wysyłane natychmiast i rozpoczyna się strumieniowanie. Każde kolejne wywołanie wypycha dane zapisane od czasu ostatniego wypchnięcia.
Zwraca: true w przypadku sukcesu, false, jeśli oxphp_finish_request() zostało już wywołane.
Tryb strumieniowania aktywuje się także automatycznie, gdy PHP ustawi Content-Type: text/event-stream. W takim przypadku możesz użyć wbudowanej funkcji flush() PHP, ale najpierw wywołaj ob_end_flush(), aby ominąć warstwę buforowania wyjścia PHP.
Przykład:
<?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): voidUsypia na określony czas. Wewnątrz handlera trybu worker działającego w Fiber wywołanie to jest kooperatywne — zawiesza bieżący Fiber, dzięki czemu podczas oczekiwania mogą być przetwarzane inne żądania. Poza Fiberem funkcja wraca do standardowego, blokującego usleep().
Parametry:
$seconds— Czas uśpienia w sekundach. Akceptowane są wartości ułamkowe (np.0.5dla 500 milisekund). Wartości0lub mniejsze powodują natychmiastowy powrót.
Zwraca: void
Przykład:
<?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): voidUsypia na określoną liczbę mikrosekund. Podobnie jak oxphp_sleep(), wewnątrz Fibera jest kooperatywne, a w innym przypadku wraca do blokującego usleep().
Parametry:
$microseconds— Czas uśpienia w mikrosekundach. Wartości0lub mniejsze powodują natychmiastowy powrót.
Zwraca: void
Przykład:
<?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): intWysyła domknięcie do wykonania na dedykowanym asynchronicznym wątku worker i natychmiast zwraca ID promise'a. Wywołujący kontynuuje wykonywanie, nie czekając na zakończenie domknięcia. Aby pobrać wynik, użyj oxphp_async_await().
Parametry:
$closure— Zdefiniowane przez użytkownika domknięcie (Closure), które ma być uruchomione na asynchronicznym wątku worker...$args— Argumenty przekazywane do domknięcia. Akceptowane są wartości skalarne (null,bool,int,float,string), ich tablice oraz instancjeOxPHP\Shared\*(jedyne obiekty, które mogą przekroczyć granicę wątków). Zasoby oraz każdy obiekt niebędącySharedsą odrzucane.
Zwraca: Całkowite ID promise'a. Przekaż je do oxphp_async_await(), oxphp_async_await_all(), oxphp_async_await_race() lub oxphp_async_await_any().
Rzuca: OxPHP\Async\AsyncException w następujących przypadkach:
- Pula asynchroniczna jest wyłączona (
ASYNC_WORKERS=0) — komunikat: "Async pool is disabled. Set ASYNC_WORKERS > 0 to enable." - Domknięcie nie jest zdefiniowane przez użytkownika
- Pula asynchroniczna jest pełna (wszystkie sloty kolejki zajęte)
- Argumenty lub zmienne przekazane przez
usezawierają obiekty lub zasoby
Zmienne przechwycone przez use w domknięciu podlegają tym samym ograniczeniom — obiekty i zasoby są odrzucane.
Przykład:
<?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): mixedBlokuje do momentu zakończenia wskazanego promise'a asynchronicznego i zwraca jego wynik. Wewnątrz Fibera trybu worker zawiesza bieżący Fiber w sposób kooperatywny, zamiast blokować wątek.
Parametry:
$promise_id— ID promise'a zwrócone przezoxphp_async()$timeout— Maksymalny czas oczekiwania w sekundach.0.0oznacza oczekiwanie w nieskończoność. Domyślnie:0.0
Zwraca: Wartość zwracaną przez asynchroniczne domknięcie.
Rzuca:
OxPHP\Async\AsyncException, jeśli pula asynchroniczna jest wyłączona (ASYNC_WORKERS=0) lub jeśli zadanie asynchroniczne rzuciło wyjątekOxPHP\Async\TimeoutException, jeśli przekroczono$timeout
Przykład:
<?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): arrayOczekuje na wszystkie promisy z tablicy i zwraca tablicę asocjacyjną mapującą każde ID promise'a na jego wynik. Promisy są oczekiwane w kolejności tablicy.
Parametry:
$promise_ids— Tablica całkowitych ID promise'ów zwróconych przezoxphp_async()$timeout— Maksymalny czas oczekiwania na jeden promise w sekundach.0.0oznacza oczekiwanie w nieskończoność. Domyślnie:0.0
Zwraca: Tablicę asocjacyjną, w której każdy klucz jest ID promise'a (liczba całkowita), a każda wartość jest wynikiem tego promise'a.
Rzuca:
OxPHP\Async\AsyncException, jeśli pula asynchroniczna jest wyłączona (ASYNC_WORKERS=0) lub jeśli którykolwiek promise zakończy się niepowodzeniemOxPHP\Async\TimeoutException, jeśli którykolwiek promise przekroczy$timeout
Przykład:
<?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Ściga ze sobą wiele promise'ów i zwraca pierwszy, który się rozstrzygnie, niezależnie od tego, czy zostanie spełniony, czy odrzucony. Pozostałe promisy nie są anulowane — działają dalej i pozostają dostępne do oczekiwania za pomocą oxphp_async_await(). Jest to odpowiednik Promise.race z JavaScriptu.
Parametry:
$promise_ids— Tablica zawierająca co najmniej jedno całkowite ID promise'a zwrócone przezoxphp_async(). Nie może być pusta.$timeout— Maksymalny czas oczekiwania na rozstrzygnięcie któregokolwiek promise'a w sekundach.0.0oznacza oczekiwanie w nieskończoność. Domyślnie:0.0
Zwraca: Tablicę asocjacyjną z dwoma kluczami:
id(int) — ID promise'a-zwycięzcyvalue(mixed) — Wartość zwrócona przez zwycięski promise
Rzuca:
OxPHP\Async\AsyncException, jeśli pula asynchroniczna jest wyłączona (ASYNC_WORKERS=0) lub jeśli zwycięski promise został odrzuconyOxPHP\Async\TimeoutException, jeśli żaden promise nie rozstrzygnie się w czasie$timeout
Przykład:
<?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): arrayZwraca wynik, gdy tylko jeden promise ZOSTANIE SPEŁNIONY. Odrzucenia są gromadzone i stają się widoczne dopiero wtedy, gdy każdy promise zostanie odrzucony. Jest to odpowiednik Promise.any z JavaScriptu — przydatny w schematach awaryjnych / redundancji, gdy potrzebujesz dowolnego działającego źródła.
Parametry:
$promise_ids— Tablica zawierająca co najmniej jedno całkowite ID promise'a zwrócone przezoxphp_async(). Nie może być pusta.$timeout— Maksymalny czas oczekiwania na pierwsze spełnienie w sekundach.0.0oznacza oczekiwanie w nieskończoność. Domyślnie:0.0
Zwraca: Tablicę asocjacyjną z dwoma kluczami:
id(int) — ID pierwszego spełnionego promise'avalue(mixed) — Wartość zwrócona przez zwycięski promise
Rzuca:
OxPHP\Async\AsyncException, jeśli pula asynchroniczna jest wyłączona (ASYNC_WORKERS=0)OxPHP\Async\AggregateAsyncException, jeśli każdy promise został odrzucony. Wyjątek przenosi wszystkie błędy poprzezgetErrors()(pozycyjnie, kluczowane 0..N-1),getErrorMap()(kluczowane po ID) orazgetPromiseIds().OxPHP\Async\TimeoutException, jeśli w czasie$timeoutżaden promise nie został spełniony.getPartialErrors()wymienia promisy, które zostały już odrzucone przed upływem terminu;getCancelledPromiseIds()wymienia te, które się nie rozstrzygnęły i zostały w związku z tym anulowane. Ich flaga anulowania jest ustawiona, a ich odbiorniki zostają porzucone — przekazanie któregokolwiek z tych ID dooxphp_async_await*()w późniejszym czasie rzuci"unknown or already-awaited promise id". Lista ta stanowi ślad audytowy, a nie kolejkę pracy do wznowienia.
Zachowanie:
- Promisy, które w chwili zwycięstwa nadal oczekiwały, pozostają dostępne do indywidualnego oczekiwania za pomocą
oxphp_async_await(). - Promisy, które zostały odrzucone przed zwycięzcą, już nie — ich wyniki zostały skonsumowane w momencie zgromadzenia ich jako kandydatów na błędy.
Przykład:
<?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): boolRejestruje klasę PHP jako dekorator opakowujący wywołania funkcji i metod. Klasa musi implementować OxPHP\Decorator\AttributeInterface. Po zarejestrowaniu OxPHP wywołuje haki before() i after() dekoratora wokół każdego wywołania funkcji lub metody pasującego do celów #[Attribute] dekoratora.
Parametry:
$class— W pełni kwalifikowana nazwa klasy dekoratora do zarejestrowania
Zwraca: true w przypadku sukcesu, false, jeśli klasa nie istnieje lub nie implementuje OxPHP\Decorator\AttributeInterface.
Przykład:
<?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): voidWykonuje callback wewnątrz nazwanego spanu. Span jest otwierany przed uruchomieniem callbacku i zamykany po jego powrocie. Zarezerwowane na potrzeby przyszłej rozszerzonej integracji callbacków.
Parametry:
$name— Nazwa spanu$callback— Obiekt wywoływalny do wykonania wewnątrz spanu$attributes— Opcjonalna tablica asocjacyjna atrybutów w postaci par klucz-wartość typu string
Zwraca: void
oxphp_apm_start()
oxphp_apm_start(string $name, ?array $attributes = null): intOtwiera nowy span i zwraca lokalne ID do późniejszego odwołania. Span staje się dzieckiem aktualnie aktywnego spanu (lub głównego spanu żądania, jeśli żaden span nie jest aktywny). Aby go zamknąć, użyj oxphp_apm_end().
Parametry:
$name— Nazwa spanu (np."cache.warm","payment.process")$attributes— Opcjonalna tablica asocjacyjna atrybutów w postaci par klucz-wartość typu string, ustawianych na spanie przy jego tworzeniu
Zwraca: Całkowite lokalne ID spanu. Przekaż je do oxphp_apm_end(), oxphp_apm_attribute() lub innych funkcji przyjmujących $span_id. Zwraca 0, gdy APM jest wyłączone.
Przykład:
<?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): voidZamyka span otwarty przez oxphp_apm_start(). Czas zakończenia spanu zostaje zapisany, a span przenosi się ze stosu aktywnego na listę zakończonych, gotowy do eksportu.
Parametry:
$span_id— Lokalne ID spanu zwrócone przezoxphp_apm_start()
Zwraca: void
Zawsze zamykaj spany w odwrotnej kolejności. Jeśli otworzysz span A, a następnie span B, zamknij B przed A. Niezamknięte spany są automatycznie zamykane na końcu żądania i oznaczane atrybutem oxphp.span.leaked=true.
oxphp_apm_attribute()
oxphp_apm_attribute(string $key, mixed $value, ?int $span_id = null): voidUstawia atrybut w postaci pary klucz-wartość na spanie. Wartości są konwertowane na ciągi znaków. Jeśli nie podano $span_id, atrybut jest dodawany do aktualnie aktywnego spanu.
Parametry:
$key— Klucz atrybutu (np."user.id","cache.hit")$value— Wartość atrybutu (string, int, float, bool lub null -- konwertowana na string)$span_id— Opcjonalne lokalne ID spanu. Gdy pominięte, celuje w bieżący span
Zwraca: void
Przykład:
<?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): voidZapisuje zdarzenie ze znacznikiem czasu na spanie. Zdarzenia są przydatne do rejestrowania odrębnych wystąpień w trakcie życia spanu (np. brak trafienia w cache, próba ponowienia, kontrola autoryzacji).
Parametry:
$name— Nazwa zdarzenia (np."cache.miss","retry")$attributes— Opcjonalna tablica asocjacyjna atrybutów zdarzenia w postaci par klucz-wartość typu string$span_id— Opcjonalne lokalne ID spanu. Gdy pominięte, celuje w bieżący span
Zwraca: void
Przykład:
<?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): voidOznacza status spanu jako błąd (kod statusu 2). Użyj tego, aby oznaczyć spany, w których wystąpił wyjątek lub niepowodzenie.
Parametry:
$exception— Wyjątek lub błąd (używany dla kontekstu; status jest ustawiany niezależnie od typu)$span_id— Opcjonalne lokalne ID spanu. Gdy pominięte, celuje w bieżący span
Zwraca: void
Przykład:
<?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): voidUstawia kod statusu i opcjonalny opis na spanie.
Parametry:
$code— Kod statusu:0= Unset,1= Ok,2= Error$description— Opcjonalny, czytelny dla człowieka opis statusu$span_id— Opcjonalne lokalne ID spanu. Gdy pominięte, celuje w bieżący span
Zwraca: void
Przykład:
<?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(): stringZwraca ID śledzenia W3C (32 znaki szesnastkowe) dla kontekstu śledzenia bieżącego żądania. Jest to ta sama wartość co $_SERVER['OXPHP_TRACE_ID'], dostępna bez superglobalnych.
Zwraca: 32-znakowy szesnastkowy ciąg ID śledzenia. Zwraca pusty ciąg, gdy APM jest wyłączone lub żaden kontekst śledzenia nie jest aktywny.
Przykład:
<?php
$traceId = oxphp_apm_trace_id();
error_log("Processing request in trace {$traceId}");oxphp_apm_span_id()
oxphp_apm_span_id(): stringZwraca ID spanu (16 znaków szesnastkowych) aktualnie aktywnego spanu. Jeśli istnieją zagnieżdżone spany, zwraca ID najbardziej wewnętrznego otwartego spanu.
Zwraca: 16-znakowy szesnastkowy ciąg ID spanu. Zwraca pusty ciąg, gdy żaden span nie jest aktywny.
oxphp_apm_header()
oxphp_apm_header(): stringZwraca wartość nagłówka traceparent W3C dla kontekstu bieżącego spanu. Użyj tego, aby propagować kontekst śledzenia do dalszych wywołań HTTP.
Zwraca: Ciąg w formacie 00-{trace_id}-{span_id}-01. Zwraca pusty ciąg, gdy żaden kontekst śledzenia nie jest aktywny.
Przykład:
<?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(): boolZwraca true, gdy przechwytywanie profilu jest aktualnie aktywne dla tego żądania — tj. profiler został wyzwolony (przez nagłówek, ciasteczko, parametr zapytania lub współczynnik próbkowania), a przechwytywanie nie zostało wstrzymane przez pause().
Przydatne do zabezpieczania kosztownej instrumentacji, która powinna działać tylko wtedy, gdy profilowanie jest włączone.
Zwraca: bool.
Przykład:
<?php
if (OxPHP\Profile\is_active()) {
OxPHP\Profile\mark('checkpoint.before_query');
}OxPHP\Profile\start()
OxPHP\Profile\start(): voidProgramowo włącza przechwytywanie profilu na pozostałą część bieżącego żądania, nawet jeśli żaden wyzwalacz nie zadziałał podczas RINIT. Ustawia tryb profilowania na PROFILE_ALL i czyści flagę wstrzymania.
Jeśli profil był już aktywny w innym trybie, to wywołanie promuje go — wszelkie spany zebrane już w niższym trybie zostają odrzucone, tak aby przechwycony profil był wewnętrznie spójny. Użyj tego, gdy chcesz włączyć profilowanie dla konkretnej ścieżki kodu bez polegania na wyzwalaczach.
Zwraca: void.
Przykład:
<?php
if ($request->header('x-debug') === 'on') {
OxPHP\Profile\start();
}OxPHP\Profile\stop()
OxPHP\Profile\stop(): voidWyłącza dalsze przechwytywanie spanów dla tego żądania. Aktualnie otwarte spany zamykają się naturalnie, w miarę jak PHP z nich wraca, dzięki czemu stos wywołań pozostaje zrównoważony — przestają być rejestrowane jedynie nowe spany.
Zwraca: void.
Przykład:
<?php
OxPHP\Profile\start();
expensive_work();
OxPHP\Profile\stop();
non_profiled_work();OxPHP\Profile\pause()
OxPHP\Profile\pause(): voidMiękki wariant stop(). Ten sam efekt (ustawia flagę wstrzymania); różnica leży w intencji — pause() sygnalizuje, że przechwytywanie zostanie później wznowione przez resume(), podczas gdy stop() tego nie robi.
Zwraca: void.
OxPHP\Profile\resume()
OxPHP\Profile\resume(): voidCzyści flagę wstrzymania ustawioną przez pause() lub stop(). Sam tryb profilu nie ulega zmianie — jeśli nigdy nie był włączony, resume() nie robi niczego zauważalnego.
Zwraca: void.
Przykład:
<?php
OxPHP\Profile\pause();
$secret = decrypt_payload($data);
OxPHP\Profile\resume();OxPHP\Profile\mark()
OxPHP\Profile\mark(string $label, ?array $attrs = null): voidDołącza zdarzenie Mark do najwyższego otwartego spanu, wraz z opcjonalnym zestawem atrybutów. Nie robi nic, gdy żaden span nie jest otwarty (np. profilowanie nieaktywne lub mark() wywołane na najwyższym poziomie żądania, poza jakąkolwiek instrumentowaną ramką).
Klucze i wartości atrybutów są rzutowane na ciągi znaków; wartości niebędące ciągami stają się pustym ciągiem.
Parametry:
$label— krótka, czytelna dla człowieka nazwa zdarzenia (np."cache.miss","db.slow_query")$attrs— opcjonalnaarray<string, scalar>par klucz/wartość dołączonych do zdarzenia
Zwraca: void.
Przykład:
<?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): voidDołącza atrybut metric.<name> do bieżącego otwartego spanu. Nie robi nic, gdy żaden span nie jest otwarty.
W przeciwieństwie do mark() (które tworzy odrębne zdarzenie), metric() zapisuje do istniejącego zestawu atrybutów spanu — przydatne do rejestrowania obserwacji liczbowych powiązanych z otaczającą operacją (pobrane wiersze, przetworzone bajty, liczba ponowień).
Parametry:
$name— identyfikator metryki; zostanie zapisany jakometric.<name>$value— wartość liczbowa (rzutowana nafloat)
Zwraca: void.
Przykład:
<?php
function search(string $query): array {
$results = $index->search($query);
OxPHP\Profile\metric('result_count', count($results));
return $results;
}Klasy i interfejsy
Rozszerzenie oxphp_sapi rejestruje następujące klasy:
HTTP
| Klasa | Opis |
|---|---|
OxPHP\Http\Request |
Obiekt żądania zwracany przez oxphp_http_request(). final — nie można go rozszerzać. |
OxPHP\Http\Attributes |
Modyfikowalny kontener atrybutów żądania (dla middleware). final. |
OxPHP\Http\Session |
Obiekt sesji dostępny przez $request->session(). final. |
OxPHP\Http\UploadedFile |
Obiekt przesłanego pliku z $request->files(). final. |
Dekoratory
| Klasa / interfejs | Opis |
|---|---|
OxPHP\Decorator\AttributeInterface |
Interfejs dla dekoratorów. Wymaga metod before(Context $ctx) i after(Context $ctx). |
OxPHP\Decorator\Context |
Obiekt kontekstu przekazywany do haków dekoratora. final. Właściwości publiczne: target, class, method, function, objectId, requestId, traceId. Metody: getParams(): array, getResult(): mixed, hasResult(): bool. Pełną dokumentację znajdziesz w Dekoratory. |
Śledzenie
| Klasa | Opis |
|---|---|
OxPHP\Apm\Trace |
Wbudowany atrybut do automatycznego tworzenia spanów. Stosuj do funkcji lub metod. |
Async
| Klasa | Opis |
|---|---|
OxPHP\Async\BorrowedProxy |
Obiekt proxy dla wartości pożyczanych między wątkami. |
Wyjątki
Wszystkie wyjątki zarejestrowane przez rozszerzenie:
| Wyjątek | Rozszerza | Kiedy rzucany |
|---|---|---|
OxPHP\Async\AsyncException |
\Exception |
Błąd w zadaniu asynchronicznym (oxphp_async_await()) lub nieprawidłowe argumenty w oxphp_async() |
OxPHP\Async\TimeoutException |
OxPHP\Async\AsyncException |
Przekroczono limit czasu w którejkolwiek z funkcji oxphp_async_await(), oxphp_async_await_all(), oxphp_async_await_race() lub oxphp_async_await_any(). Dla limitów czasu oxphp_async_await_any() wypełniane są akcesory getPartialErrors(): array<int, \Throwable> oraz getCancelledPromiseIds(): list<int>; dla pozostałych miejsc wywołania oba zwracają []. |
OxPHP\Async\AggregateAsyncException |
OxPHP\Async\AsyncException |
Rzucany przez oxphp_async_await_any(), gdy każdy promise został odrzucony. Metody: getErrors(): list<\Throwable> (pozycyjnie, kluczowane 0..N-1 według pozycji wejściowej), getErrorMap(): array<int, \Throwable> (kluczowane po ID promise'a), getPromiseIds(): list<int> (ID promise'ów wejściowych w kolejności). |
OxPHP\Async\BorrowException |
\Exception |
Błąd przy pożyczaniu wartości między wątkami |
OxPHP\Http\Exception\NoActiveRequestException |
\RuntimeException |
Wywołanie oxphp_http_request() poza aktywnym żądaniem |
OxPHP\Http\Exception\AsyncContextException |
NoActiveRequestException |
Wywołanie oxphp_http_request() wewnątrz callbacku oxphp_async() |
OxPHP\Http\Exception\WorkerIdleException |
NoActiveRequestException |
Wywołanie oxphp_http_request() w trybie worker pomiędzy żądaniami |
OxPHP\Decorator\RejectedException |
\Exception |
Dekorator odrzucił wywołanie funkcji/metody |
Weryfikacja rozszerzenia
Możesz zweryfikować, czy rozszerzenie OxPHP jest załadowane, oraz sprawdzić wszystkie zarejestrowane funkcje:
<?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
// )Podstawowe funkcje SAPI (do oxphp_register_decorator) występują jako pierwsze; rodziny oxphp_async_* i oxphp_apm_* — a także SDK OxPHP\Profile\*, gdy profiler jest wbudowany — są dołączane przez ich wtyczki podczas inicjalizacji modułu. Traktuj tę listę jako poglądową: dokładny zestaw i kolejność zależą od tego, które wtyczki są skompilowane w danej wersji.
Zgodność z PHP-FPM
Jeśli Twój kod musi działać zarówno na OxPHP, jak i na PHP-FPM, użyj opakowań awaryjnych:
<?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
}Rodzina funkcji oxphp_async() jest zawsze rejestrowana w OxPHP, więc function_exists('oxphp_async') zwraca true nawet wtedy, gdy ASYNC_WORKERS=0. Gdy pula jest wyłączona, wywołanie dowolnej funkcji asynchronicznej rzuca OxPHP\Async\AsyncException. Jeśli Twój kod musi obsługiwać obie konfiguracje, przechwytuj wyjątek, zamiast sprawdzać function_exists().
Zobacz też
- HTTP Request API -- obiektowy dostęp do danych żądania przez
oxphp_http_request() - Tryb worker -- trwała pętla worker i cykl życia żądania
- Server-Sent Events -- strumieniowanie w czasie rzeczywistym z
oxphp_stream_flush() - Wczesna odpowiedź -- przetwarzanie w tle z
oxphp_finish_request() - Superglobalne -- jak OxPHP wypełnia
$_SERVER,$_GET,$_POSTi inne superglobalne - Śledzenie rozproszone i APM -- W3C Trace Context, eksport OTel oraz SDK
oxphp_apm_*() - Dokumentacja konfiguracji --
WORKER_MODE_ENABLED,ENTRY_FILE,PHP_WORKERSi inne zmienne środowiskowe