Skip to content

PHP 服务端 SDK

官方 PHP 服务端 SDK —— Packagist 包名 captchala/captchala-php

SDK 帮你做三件事:

  1. 校验(Validate)—— 验证浏览器 SDK 返回的 pt_ pass token。
  2. 签发(Issue)—— 签发一次性 sct_ server token,将本次挑战绑定到具体 action / IP / UID。
  3. 审核(Moderate)—— 多模态(文本 + 图片)内容审核,走 dashboard 同款 OpenAI 兼容管道。

安装

bash
composer require captchala/captchala-php

依赖:PHP ≥ 8.0ext-json。优先用 cURL,缺失则 fallback 到 file_get_contents

校验(pt_ token)

php
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());   // 例: token_expired、client_ip_mismatch
}
// 验证通过, 继续业务流程

如果原 server_token 签发时带了 bind_uid, 校验时核对 uid 是否匹配预期用户:

php
if ($result->getUid() !== $expectedUserId) {
    http_response_code(400);
    exit('user mismatch');
}

如果 token 绑定了 IP, 校验时也传用户 IP:

php
$client->validate($token, false, $request->ip());

签发 server token

注册 / 登录 / 支付等高价值场景推荐流程:后端签发一次性 sct_ token, 下发给前端, 浏览器作为 serverToken 传给组件。token 单次消费, 绑定 action, 可选绑定 IP / UID。

php
$issue = $client->issueServerToken(
    action:    'login',
    bindingIp: $request->ip(),
    ttl:       300,         // 秒, 默认 300
    maxUses:   5,           // SDK 重试预算
    bindUid:   $user->id,   // 配合 ValidateResult::getUid() 在校验侧核对
);

if (!$issue->isOk()) {
    return ['error' => $issue->getError()];   // rate_limit_exceeded / invalid_action ...
}

return ['server_token' => $issue->getToken()];  // 下发给浏览器

内容审核

多模态 —— 接受文本 + 图片 URL 混合(OpenAI 兼容格式):

php
$result = $client->moderationCheck([
    ['type' => 'text', 'text' => $userComment],
    ['type' => 'image_url', 'image_url' => ['url' => $uploadedImageUrl]],
], userId: $user->id);

if (!$result->isOk()) {
    // 请求出错: invalid_credentials / no_content / 网络失败 ...
    return ['error' => $result->getError()];
}

if ($result->isFlagged()) {
    // 上游模型判定违规, 看是哪个 category
    if ($result->hasCategory('violence', 'csam')) {
        // 硬阻断
    }
}

纯文本快捷方式:

php
$result = $client->moderationText('user comment here', userId: $user->id);

Category 列表由上游模型决定(如 violencehatesexualself-harm),用 getCategories() 防御性遍历, 不要硬编码固定集合。

Result 类

方法
ValidateResultisValid()getError()getUid()getChallengeId()getAction()isOffline()isClientOnly()getWarning()toArray()
IssueResultisOk()getToken()getExpiresIn()getIssuedAt()getError()getMessage()toArray()
ModerationResultisOk()isFlagged()hasCategory(...$names)getCategories()getContentType()getRaw()getError()getMessage()toArray()

链接

MIT-licensed examples · CaptchaLa is operated independently