
ترجمة المحتوى المهيكل من PHP باستخدام PolyLingo SDK
By Robert M
ترجمة المحتوى المهيكل من PHP باستخدام PolyLingo SDK
تتوفر الآن مكتبة PolyLingo PHP SDK على Packagist. قم بتثبيتها باستخدام Composer، ومرر لها نصًا عاديًا أو Markdown أو JSON أو HTML، واحصل على الترجمات بكل لغة تحتاجها — دون الحاجة لكتابة HTTP الخام أو القلق بشأن تلف هيكلك أثناء النقل.
يغطي هذا المنشور التثبيت، والمصادقة، وكامل واجهة المكتبة: الترجمة المتزامنة، طلبات الدُفعات، الوظائف غير المتزامنة، والتعامل مع الأخطاء.
التثبيت
يتطلب PHP 7.4 أو أحدث. قم بالتثبيت عبر Composer:
composer require usepolylingo/polylingo
تعتمد المكتبة على 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 (دقيقتان)
]);
ترجمة المحتوى
نص عادي، Markdown، JSON، أو HTML
مرر المحتوى ومصفوفة من رموز اللغات المستهدفة إلى translate(). حقل format يخبر المكتبة بنوع المحتوى الذي تتعامل معه:
$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، ويسمح لك بالاستطلاع عن النتيجة. المكتبة تدير هذا بطريقتين.
وضع في قائمة الانتظار والاستطلاع يدويًا
$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 "Queue position: {$queuePosition}\n";
// },
]);
$translations = $done['translations'];
$usage = $done['usage'];
تُطلق دالة رد الاتصال onProgress في كل استطلاع مع موقع الطابور الحالي إذا أعاد API واحدًا، أو null إذا لم يكن متاحًا. استخدمها لتسجيل التقدم أو تحديث واجهة المستخدم.
نقاط النهاية المساعدة
ثلاث نقاط نهاية خفيفة الوزن لا تحتاج إلى معلمات سوى المصادقة:
$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 يعيد استهلاك الرموز للشهر الميلادي الحالي للحساب المصادق عليه.
التعامل مع الأخطاء
جميع أخطاء المكتبة ترث من 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() تعطيك معرف الوظيفة الفاشلة لتسجيلها أو عرضها للمستخدم.
مرجع سريع
| الطريقة | نقطة النهاية | هل تتطلب مصادقة |
|---|---|---|
$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 + استطلاع | نعم |
ابدأ
المكتبة موجودة على Packagist في usepolylingo/polylingo. التوثيق الكامل للـ API على usepolylingo.com/docs.
الطبقة المجانية تشمل 50,000 رمز شهريًا. لا حاجة لبطاقة ائتمان.
composer require usepolylingo/polylingo