SDK PHP Server
SDK oficial server-side em PHP — publicado como captchala/captchala-php no Packagist.
Três tarefas que o SDK executa para você:
- Validar — verifica um pass token
pt_vindo do SDK do navegador. - Emitir — cunha um server token
sct_de uso único para vincular o próximo desafio a uma action / IP / UID específica. - Moderar — moderação de conteúdo multimodal (texto + imagem) contra o mesmo pipeline compatível com OpenAI usado pelo painel.
Instalação
composer require captchala/captchala-phpRequer PHP ≥ 8.0 com ext-json. Usa cURL quando disponível, com fallback para file_get_contents.
Validar (token pt_)
use Captchala\Client;
$client = new Client('your_app_key', 'your_app_secret');
$result = $client->validate($_POST['captcha_token']);
if (!$result->isValid()) {
http_response_code(400);
exit($result->getError()); // e.g. "token_expired", "client_ip_mismatch"
}
// Verification passed; proceed with the request.Se você emitiu o server_token original com bind_uid, compare o uid retornado com o usuário que de fato espera:
if ($result->getUid() !== $expectedUserId) {
http_response_code(400);
exit('user mismatch');
}Se vinculou o token a um IP, passe o IP do usuário também no lado da verificação:
$client->validate($token, false, $request->ip());Emitir um server token
Para fluxos de alto valor (login, cadastro, pagamento) o padrão recomendado é: o backend cunha um token sct_ de uso único, entrega ao navegador, o navegador o passa como a prop serverToken. Cada token é de uso único, com escopo de action e opcionalmente vinculado a IP / UID no momento da emissão.
$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 browserModerar conteúdo
Multimodal — aceita uma mistura de texto e URLs de imagem em formato compatível com OpenAI:
$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
}
}Atalho para texto puro:
$result = $client->moderationText('user comment here', userId: $user->id);As categorias são definidas pelo modelo (ex.: violence, hate, sexual, self-harm); itere getCategories() de forma defensiva em vez de fixar um conjunto rígido.
Classes de resultado
| Classe | Métodos |
|---|---|
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() |