Skip to content

PHP Server SDK

SDK phía máy chủ chính thức cho PHP — phát hành dưới dạng captchala/captchala-php trên Packagist.

Ba việc SDK xử lý giúp bạn:

  1. Xác minh — kiểm tra pass token pt_ từ SDK trình duyệt.
  2. Phát hành — tạo một server token sct_ dùng một lần để gắn thử thách sắp tới với một hành động / IP / UID cụ thể.
  3. Kiểm duyệt — kiểm duyệt nội dung đa phương thức (văn bản + hình ảnh) qua cùng pipeline tương thích OpenAI mà bảng điều khiển sử dụng.

Cài đặt

bash
composer require captchala/captchala-php

Yêu cầu PHP ≥ 8.0 với ext-json. Dùng cURL khi có sẵn, dự phòng file_get_contents.

Xác minh (token pt_)

Truyền IP của người dùng cuối làm tham số thứ ba (từ CF-Connecting-IP / X-Forwarded-For, dự phòng về REMOTE_ADDR). Tùy chọn, nhưng nên truyền — nó được dùng cho các kiểm tra rủi ro bổ sung.

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 '';
}

Không có sẵn IP? Dùng $client->validate($_POST['captcha_token']) — vẫn xác minh được, chỉ là thiếu tín hiệu rủi ro dựa trên IP bổ sung.

Nếu bạn phát hành server_token ban đầu với bind_uid, hãy so sánh uid trả về với người dùng bạn thực sự mong đợi:

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

Phát hành server token

Đối với các luồng quan trọng (đăng nhập, đăng ký, thanh toán), mẫu được khuyến nghị là: backend phát hành một token sct_ dùng một lần, trao cho trình duyệt, trình duyệt truyền nó làm prop serverToken. Mỗi token dùng một lần, giới hạn theo hành động, và có thể tùy chọn gắn với IP / UID tại thời điểm phát hành.

php
$issue = $client->issueServerToken(
    action:    'login',
    bindingIp: $request->ip(),
    ttl:       300,         // giây; mặc định 300
    maxUses:   5,           // ngân sách thử lại của SDK
    bindUid:   $user->id,   // ghép với ValidateResult::getUid() khi xác minh
);

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

return ['server_token' => $issue->getToken()];  // trao cho trình duyệt

Kiểm duyệt nội dung

Đa phương thức — nhận hỗn hợp văn bản và URL hình ảnh ở định dạng tương thích OpenAI:

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

if (!$result->isOk()) {
    // lỗi yêu cầu: invalid_credentials, no_content, lỗi truyền tải, ...
    return ['error' => $result->getError()];
}

if ($result->isFlagged()) {
    // model phía trên đã đánh dấu; xem các danh mục để biết lý do
    if ($result->hasCategory('violence', 'csam')) {
        // chặn cứng
    }
}

Cách rút gọn cho văn bản thuần:

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

Danh mục do model định nghĩa (ví dụ violence, hate, sexual, self-harm); hãy lặp qua getCategories() một cách phòng vệ thay vì gán cứng một tập cố định.

Lớp kết quả

LớpPhương thức
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()

Liên kết

MIT-licensed examples · CaptchaLa is operated independently