
使用 PolyLingo SDK 翻译来自 PHP 的结构化内容
By Robert M
使用 PolyLingo SDK 翻译 PHP 结构化内容
PolyLingo PHP SDK 现已在 Packagist 上可用。通过 Composer 安装,传入纯文本、Markdown、JSON 或 HTML 字符串,即可获得所需语言的翻译——无需编写原始 HTTP 请求,也不用担心结构在传输过程中被破坏。
本文涵盖安装、认证以及 SDK 的全部功能:同步翻译、批量请求、异步任务和错误处理。
安装
需要 PHP 7.4 或更高版本。通过 Composer 安装:
composer require usepolylingo/polylingo
SDK 依赖 guzzlehttp/guzzle ^7.8 和 psr/http-client ^1.0,这两个依赖会自动安装。
设置客户端
创建一个 PolyLingo 实例,并在应用中复用。唯一必需的选项是你的 API 密钥:
<?php
use PolyLingo\PolyLingo;
$client = new PolyLingo([
'apiKey' => getenv('POLYLINGO_API_KEY'),
]);
将 API 密钥存储在环境变量中,切勿硬编码或提交到版本控制。
两个值得了解的可选设置:
$client = new PolyLingo([
'apiKey' => getenv('POLYLINGO_API_KEY'),
'baseURL' => 'https://api.usepolylingo.com/v1', // 默认,针对自托管实例可覆盖
'timeout' => 120_000, // 毫秒,默认是 120000(2 分钟)
]);
翻译内容
纯文本、Markdown、JSON 或 HTML
传入内容和目标语言代码数组给 translate()。format 字段告诉 SDK 处理的内容类型:
$result = $client->translate([
'content' => '# Hello',
'targets' => ['es', 'fr', 'de'],
'format' => 'markdown',
]);
$es = $result['translations']['es'];
$tokens = $result['usage']['total_tokens'];
format 选项接受 plain、markdown、json 或 html。如果省略,API 会自动根据内容检测格式。你也可以传入 source 语言提示和 model 值,支持 standard(默认)或 advanced。
格式保持是这里的关键行为。对于 json 内容,只有字符串值会被翻译。键、嵌套、数组和非字符串类型保持不变。对于 markdown,标题保持标题,代码块原样保留,链接 URL 不被修改。对于 html,标签和属性保持不变,仅翻译文本节点。
翻译 JSON 本地化文件
一个常见用例是翻译本地化文件。将整个对象作为 JSON 字符串发送:
$source = json_decode(file_get_contents('messages/en.json'), true);
$result = $client->translate([
'content' => json_encode($source),
'format' => 'json',
'targets' => ['de', 'fr', 'ja'],
]);
foreach (['de', 'fr', 'ja'] as $locale) {
$translated = json_decode($result['translations'][$locale], true);
file_put_contents(
"messages/{$locale}.json",
json_encode($translated, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n"
);
}
一次请求处理所有三个语言。每个输出文件中的键保持不变。
批量请求
当你有多个独立内容项需要翻译时,使用 batch()。单次请求最多可发送 100 个项目,每个项目有自己的 id 和可选的 format:
$batch = $client->batch([
'items' => [
['id' => 'hero_title', 'content' => 'Welcome back', 'format' => 'plain'],
['id' => 'hero_subtitle', 'content' => 'Here is what is new today', 'format' => 'plain'],
['id' => 'cta', 'content' => 'Get started', 'format' => 'plain'],
],
'targets' => ['es', 'fr'],
]);
foreach ($batch['results'] as $row) {
echo $row['id'] . ': ' . $row['translations']['es'] . "\n";
}
所有项目共享相同的 targets 数组。响应中保留了你传入的每个项目的 id,方便你将结果映射回原始数据,无需依赖顺序。
异步任务
对于长时间运行的翻译(大型文档、多个目标语言或两者兼有),任务 API 接受请求后立即返回一个 job_id,并允许你轮询结果。SDK 提供两种处理方式。
手动排队和轮询
$accepted = $client->jobs->create([
'content' => file_get_contents('long-article.md'),
'targets' => ['es', 'fr', 'de', 'ja', 'zh'],
'format' => 'markdown',
]);
$jobId = $accepted['job_id'];
// 轮询直到任务达到终态
do {
sleep(5);
$state = $client->jobs->get($jobId);
} while ($state['status'] === 'pending' || $state['status'] === 'processing');
if ($state['status'] === 'complete') {
$translations = $state['translations'];
}
一次调用轮询直到完成
如果不需要手动控制,jobs->translate() 会帮你处理轮询循环:
$done = $client->jobs->translate([
'content' => file_get_contents('long-article.md'),
'targets' => ['es', 'fr', 'de'],
'format' => 'markdown',
// 可选覆盖(显示默认值):
// 'pollInterval' => 5000, // 轮询间隔,毫秒,默认 5000
// 'timeout' => 1_200_000, // 总等待时间,默认 20 分钟
// 'onProgress' => function (?int $queuePosition) {
// echo "队列位置: {$queuePosition}\n";
// },
]);
$translations = $done['translations'];
$usage = $done['usage'];
onProgress 回调在每次轮询时触发,传入当前队列位置(如果 API 返回),否则为 null。可用于记录进度或更新 UI。
实用端点
三个轻量级端点只需认证,无需其他参数:
$health = $client->health();
// ['status' => 'ok', 'timestamp' => '...']
$langs = $client->languages();
// ['languages' => [['code' => 'en', 'name' => 'English', 'rtl' => false], ...]]
$usage = $client->usage();
// ['usage' => ['tokens_used' => 12000, 'tokens_remaining' => 88000, ...]]
GET /health 和 GET /languages 不需要 API 密钥。GET /usage 返回当前日历月认证账户的令牌使用情况。
错误处理
所有 SDK 错误都继承自 PolyLingo\Errors\PolyLingoException。捕获你想区别处理的具体子类型:
use PolyLingo\Errors\AuthException;
use PolyLingo\Errors\JobFailedException;
use PolyLingo\Errors\PolyLingoException;
use PolyLingo\Errors\RateLimitException;
try {
$result = $client->translate([
'content' => '# Hello',
'targets' => ['es'],
'format' => 'markdown',
]);
} catch (AuthException $e) {
// HTTP 401 — 无效、缺失或被撤销的 API 密钥
} catch (RateLimitException $e) {
// HTTP 429 — 达到每分钟限制
$retryAfter = $e->getRetryAfter(); // int|null 秒数
} catch (JobFailedException $e) {
// 异步任务达到失败终态
$jobId = $e->getJobId();
} catch (PolyLingoException $e) {
// 其他所有 API 错误
$httpStatus = $e->getHttpStatus();
$errorCode = $e->getErrorCode(); // 例如 "invalid_request", "translation_error"
}
RateLimitException::getRetryAfter() 返回在 API 包含该头时需等待的秒数,否则返回 null。JobFailedException::getJobId() 返回失败任务的 ID,方便记录或向用户展示。
快速参考
| 方法 | 端点 | 是否需要认证 |
|---|---|---|
$client->health() | GET /health | 否 |
$client->languages() | GET /languages | 否 |
$client->translate() | POST /translate | 是 |
$client->batch() | POST /translate/batch | 是 |
$client->usage() | GET /usage | 是 |
$client->jobs->create() | POST /jobs | 是 |
$client->jobs->get($id) | GET /jobs/:id | 是 |
$client->jobs->translate() | POST /jobs + 轮询 | 是 |
快速开始
SDK 可在 Packagist 上找到:usepolylingo/polylingo。完整 API 文档见 usepolylingo.com/docs。
免费套餐每月包含 50,000 个令牌,无需信用卡。
composer require usepolylingo/polylingo