블로그로 돌아가기
Terminal window showing a Composer install command for the PolyLingo PHP SDK alongside a short PHP translate call and its JSON output.

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.8psr/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,       // 폴링 간격(ms), 기본 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 /healthGET /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

API 키 받기