
Tłumaczenie treści strukturalnych z PHP za pomocą PolyLingo SDK
By Robert M
Tłumacz ustrukturyzowaną zawartość z PHP za pomocą SDK PolyLingo
SDK PolyLingo PHP jest teraz dostępne na Packagist. Zainstaluj je za pomocą Composera, przekaż mu ciąg zwykłego tekstu, Markdown, JSON lub HTML i otrzymaj tłumaczenia na każdy potrzebny język — bez pisania surowych zapytań HTTP i bez obaw o uszkodzenie struktury podczas przesyłania.
Ten wpis obejmuje instalację, uwierzytelnianie oraz pełen zakres SDK: tłumaczenia synchroniczne, żądania wsadowe, zadania asynchroniczne i obsługę błędów.
Instalacja
Wymaga PHP 7.4 lub nowszego. Zainstaluj przez Composera:
composer require usepolylingo/polylingo
SDK zależy od guzzlehttp/guzzle ^7.8 oraz psr/http-client ^1.0. Oba są instalowane automatycznie.
Konfiguracja klienta
Utwórz pojedynczą instancję PolyLingo i używaj jej w całej aplikacji. Jedyną wymaganą opcją jest Twój klucz API:
<?php
use PolyLingo\PolyLingo;
$client = new PolyLingo([
'apiKey' => getenv('POLYLINGO_API_KEY'),
]);
Przechowuj swój klucz API w zmiennej środowiskowej. Nigdy nie wpisuj go na stałe ani nie dodawaj do kontroli wersji.
Dwie opcjonalne ustawienia warte poznania:
$client = new PolyLingo([
'apiKey' => getenv('POLYLINGO_API_KEY'),
'baseURL' => 'https://api.usepolylingo.com/v1', // domyślny, nadpisz dla instancji hostowanych samodzielnie
'timeout' => 120_000, // milisekundy, domyślnie 120000 (2 minuty)
]);
Tłumaczenie zawartości
Zwykły tekst, Markdown, JSON lub HTML
Przekaż zawartość i tablicę kodów języków docelowych do translate(). Pole format informuje SDK, z jakim typem zawartości ma do czynienia:
$result = $client->translate([
'content' => '# Hello',
'targets' => ['es', 'fr', 'de'],
'format' => 'markdown',
]);
$es = $result['translations']['es'];
$tokens = $result['usage']['total_tokens'];
Opcja format akceptuje wartości plain, markdown, json lub html. Jeśli ją pominiesz, API automatycznie wykryje format na podstawie zawartości. Możesz też podać wskazówkę języka źródłowego source oraz wartość model standard (domyślny) lub advanced.
Zachowanie formatu jest tutaj kluczowe. Dla zawartości json tłumaczone są tylko wartości tekstowe. Klucze, zagnieżdżenia, tablice i typy niebędące tekstem są zwracane dokładnie tak, jak je wysłałeś. Dla markdown nagłówki pozostają nagłówkami, bloki kodu są pozostawione dosłownie, a adresy URL linków nie są zmieniane. Dla html tagi i atrybuty są zachowane, a tłumaczone są tylko węzły tekstowe.
Tłumaczenie pliku locale JSON
Typowym przypadkiem użycia jest tłumaczenie pliku locale. Wyślij cały obiekt jako ciąg 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"
);
}
Jedno żądanie obsługuje wszystkie trzy locale. Klucze pozostają niezmienione w każdym pliku wyjściowym.
Żądania wsadowe
Użyj batch(), gdy masz wiele oddzielnych elementów zawartości do przetłumaczenia. Możesz wysłać do 100 elementów w jednym żądaniu, każdy z własnym id i opcjonalnym 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";
}
Wszystkie elementy dzielą tę samą tablicę targets. Odpowiedź zachowuje id, które podałeś dla każdego elementu, dzięki czemu możesz powiązać wyniki z oryginalnymi danymi bez polegania na kolejności.
Zadania asynchroniczne
Dla długotrwałych tłumaczeń (duże dokumenty, wiele celów lub oba) API zadań przyjmuje żądanie, zwraca natychmiast job_id i pozwala na odpytywanie o wynik. SDK obsługuje to na dwa sposoby.
Kolejkowanie i ręczne odpytywanie
$accepted = $client->jobs->create([
'content' => file_get_contents('long-article.md'),
'targets' => ['es', 'fr', 'de', 'ja', 'zh'],
'format' => 'markdown',
]);
$jobId = $accepted['job_id'];
// Odpytywanie aż zadanie osiągnie status końcowy
do {
sleep(5);
$state = $client->jobs->get($jobId);
} while ($state['status'] === 'pending' || $state['status'] === 'processing');
if ($state['status'] === 'complete') {
$translations = $state['translations'];
}
Jedno wywołanie, które odpytywa aż do zakończenia
Jeśli nie potrzebujesz ręcznej kontroli, jobs->translate() obsługuje pętlę odpytywania za Ciebie:
$done = $client->jobs->translate([
'content' => file_get_contents('long-article.md'),
'targets' => ['es', 'fr', 'de'],
'format' => 'markdown',
// Opcjonalne nadpisania (pokazane wartości domyślne):
// 'pollInterval' => 5000, // ms między odpytywaniem, domyślnie 5000
// 'timeout' => 1_200_000, // całkowity czas oczekiwania, domyślnie 20 minut
// 'onProgress' => function (?int $queuePosition) {
// echo "Queue position: {$queuePosition}\n";
// },
]);
$translations = $done['translations'];
$usage = $done['usage'];
Funkcja zwrotna onProgress jest wywoływana przy każdym odpytywaniu z aktualną pozycją w kolejce, jeśli API ją zwraca, lub null, jeśli nie jest dostępna. Użyj jej do logowania postępu lub aktualizacji interfejsu użytkownika.
Punkty końcowe narzędziowe
Trzy lekkie punkty końcowe nie wymagają parametrów poza uwierzytelnianiem:
$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 i GET /languages nie wymagają klucza API. GET /usage zwraca zużycie tokenów za bieżący miesiąc kalendarzowy dla uwierzytelnionego konta.
Obsługa błędów
Wszystkie błędy SDK rozszerzają PolyLingo\Errors\PolyLingoException. Przechwytuj konkretne podtypy, które chcesz obsłużyć inaczej:
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 — nieprawidłowy, brakujący lub cofnięty klucz API
} catch (RateLimitException $e) {
// HTTP 429 — osiągnięto limit na minutę
$retryAfter = $e->getRetryAfter(); // int|null sekund
} catch (JobFailedException $e) {
// Zadanie asynchroniczne osiągnęło stan końcowy z błędem
$jobId = $e->getJobId();
} catch (PolyLingoException $e) {
// Wszystkie inne błędy API
$httpStatus = $e->getHttpStatus();
$errorCode = $e->getErrorCode(); // np. "invalid_request", "translation_error"
}
RateLimitException::getRetryAfter() zwraca liczbę sekund do odczekania przed ponowną próbą, jeśli API zawiera ten nagłówek, lub null, jeśli go nie ma. JobFailedException::getJobId() zwraca ID nieudanego zadania, abyś mógł je zalogować lub pokazać użytkownikowi.
Szybkie odniesienie
| Metoda | Punkt końcowy | Wymaga uwierzytelnienia |
|---|---|---|
$client->health() | GET /health | Nie |
$client->languages() | GET /languages | Nie |
$client->translate() | POST /translate | Tak |
$client->batch() | POST /translate/batch | Tak |
$client->usage() | GET /usage | Tak |
$client->jobs->create() | POST /jobs | Tak |
$client->jobs->get($id) | GET /jobs/:id | Tak |
$client->jobs->translate() | POST /jobs + polling | Tak |
Zacznij
SDK jest dostępne na Packagist pod usepolylingo/polylingo. Pełna dokumentacja API jest dostępna na usepolylingo.com/docs.
Darmowy poziom obejmuje 50 000 tokenów miesięcznie. Nie jest wymagana karta kredytowa.
composer require usepolylingo/polylingo