--- title: PHP-Server-SDK --- # PHP-Server-SDK Offizielles serverseitiges PHP-SDK — veröffentlicht als [`captchala/captchala-php`](https://packagist.org/packages/captchala/captchala-php) auf Packagist. Drei Aufgaben, die das SDK für Sie übernimmt: 1. **Validate** — verifiziert einen `pt_`-Pass-Token aus dem Browser-SDK. 2. **Issue** — stellt einen Einmal-`sct_`-Server-Token aus, um die anstehende Challenge an eine bestimmte action / IP / UID zu binden. 3. **Moderate** — multimodale (Text + Bild) Content-Moderation gegen dieselbe OpenAI-kompatible Pipeline, die auch das Dashboard verwendet. ## Installation ```bash composer require captchala/captchala-php ``` Erfordert **PHP ≥ 8.0** mit `ext-json`. Nutzt cURL, falls verfügbar, und fällt auf `file_get_contents` zurück. ## Validate (`pt_`-Token) Übergeben Sie die IP des Endnutzers als drittes Argument (aus `CF-Connecting-IP` / `X-Forwarded-For`, mit Rückfall auf `REMOTE_ADDR`). Optional, aber **empfohlen** — sie wird für zusätzliche Risikoprüfungen verwendet. ```php use Captchala\Client; $client = new Client('your_app_key', 'your_app_secret'); $result = $client->validate($_POST['captcha_token'], false, captchala_client_ip()); if (!$result->isValid()) { http_response_code(400); exit($result->getError()); // e.g. "token_expired" } // Verification passed; proceed with the request. // $result->getCaptchaArgs() has platform / user_ip / referer / pkg / solved_at / risk_score // Real end-user IP behind a CDN / proxy function captchala_client_ip(): string { foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'REMOTE_ADDR'] as $h) { if (!empty($_SERVER[$h])) { $ip = trim(explode(',', $_SERVER[$h])[0]); if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip; } } return ''; } ``` Keine IP zur Hand? Verwenden Sie `$client->validate($_POST['captcha_token'])` — die Verifizierung funktioniert weiterhin, nur ohne das zusätzliche IP-basierte Risikosignal. Falls Sie den ursprünglichen `server_token` mit `bind_uid` ausgestellt haben, vergleichen Sie die zurückgegebene `uid` mit dem tatsächlich erwarteten Nutzer: ```php if ($result->getUid() !== $expectedUserId) { http_response_code(400); exit('user mismatch'); } ``` ## Server-Token ausstellen Für hochwertige Flows (Anmeldung, Registrierung, Bezahlung) ist das empfohlene Muster: Das Backend stellt einen Einmal-`sct_`-Token aus, übergibt ihn an den Browser, und der Browser reicht ihn als `serverToken`-Prop weiter. Jeder Token ist Einmal-, action-bezogen und optional zum Zeitpunkt der Ausstellung an IP / UID gebunden. ```php $issue = $client->issueServerToken( action: 'login', bindingIp: $request->ip(), ttl: 300, // seconds; default 300 maxUses: 5, // SDK retry budget bindUid: $user->id, // pair with ValidateResult::getUid() on verify ); if (!$issue->isOk()) { return ['error' => $issue->getError()]; // rate_limit_exceeded, invalid_action, ... } return ['server_token' => $issue->getToken()]; // hand to browser ``` ## Inhalte moderieren Multimodal — akzeptiert eine Mischung aus Text- und Bild-URLs im OpenAI-kompatiblen Format: ```php $result = $client->moderationCheck([ ['type' => 'text', 'text' => $userComment], ['type' => 'image_url', 'image_url' => ['url' => $uploadedImageUrl]], ], userId: $user->id); if (!$result->isOk()) { // request error: invalid_credentials, no_content, transport failure, ... return ['error' => $result->getError()]; } if ($result->isFlagged()) { // upstream model flagged; inspect categories for the why if ($result->hasCategory('violence', 'csam')) { // hard block } } ``` Reine-Text-Abkürzung: ```php $result = $client->moderationText('user comment here', userId: $user->id); ``` Kategorien werden vom Modell definiert (z. B. `violence`, `hate`, `sexual`, `self-harm`); iterieren Sie `getCategories()` defensiv, statt einen festen Satz hart zu kodieren. ## Result-Klassen | Klasse | Methoden | |---|---| | `ValidateResult` | `isValid()`, `getError()`, `getUid()`, `getChallengeId()`, `getAction()`, `isOffline()`, `isClientOnly()`, `getWarning()`, `toArray()` | | `IssueResult` | `isOk()`, `getToken()`, `getExpiresIn()`, `getIssuedAt()`, `getError()`, `getMessage()`, `toArray()` | | `ModerationResult` | `isOk()`, `isFlagged()`, `hasCategory(...$names)`, `getCategories()`, `getContentType()`, `getRaw()`, `getError()`, `getMessage()`, `toArray()` | ## Links - [Packagist](https://packagist.org/packages/captchala/captchala-php) · [GitHub](https://github.com/Captcha-La/captchala-php) - [Web-SDK-Übersicht](/de/web-sdk) · [API-Referenz](/de/api-reference)