deeplcom/deepl-php
Official PHP client for the DeepL API. Translate text and documents with DeepL’s high-quality machine translation using a simple DeepLClient. Install via Composer, supports PHP 7.3+, and includes configurable options for requests.
Installation:
composer require deeplcom/deepl-php
Ensure your project uses PHP 8.1+ (recommended) or at least PHP 7.3.
Authentication:
.env file):
DEEPL_AUTH_KEY=f63c02c5-f056-...
First Translation:
use DeepL\DeepLClient;
$client = new DeepLClient(config('deepl.auth_key'));
$result = $client->translateText('Hello, world!', 'en', 'fr');
echo $result->text; // Output: "Bonjour, le monde !"
$translations = $client->translateText(
['Bonjour!', 'Hola!'],
null, // Auto-detect source
'en'
);
$texts = ['Text 1', 'Text 2'];
$results = $client->translateText($texts, 'en', 'es');
$options = [
'formality' => 'more',
'preserve_formatting' => true,
'custom_instructions' => ['Translate idioms literally.'],
];
$result = $client->translateText('Hello!', 'en', 'de', $options);
use Illuminate\Support\Facades\Storage;
$sourcePath = storage_path('documents/manual.docx');
$targetPath = storage_path('documents/manual_de.docx');
$client->translateDocument($sourcePath, $targetPath, 'en', 'de');
$result = $client->rephraseText(
'This is urgent.',
'en-US',
['tone' => 'diplomatic']
);
try {
$result = $client->translateText('...', 'en', 'fr');
} catch (\DeepL\DeepLException $e) {
Log::error('DeepL Error: ' . $e->getMessage());
return back()->with('error', 'Translation failed. Using fallback.');
}
Service Provider Binding:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(DeepLClient::class, function ($app) {
return new DeepLClient(config('deepl.auth_key'));
});
}
API Resource Responses:
// app/Http/Controllers/TranslationController.php
public function translate(Request $request)
{
$text = $request->input('text');
$result = app(DeepLClient::class)->translateText($text, 'en', 'fr');
return response()->json(['translated' => $result->text]);
}
Caching Translations:
$cacheKey = "translation_{$text}_{$targetLang}";
$translation = Cache::remember($cacheKey, now()->addHours(1), function () use ($text, $targetLang) {
return app(DeepLClient::class)->translateText($text, null, $targetLang)->text;
});
Queueing Long-Running Tasks (e.g., document translation):
// app/Jobs/TranslateDocumentJob.php
public function handle()
{
$client = new DeepLClient(config('deepl.auth_key'));
$client->translateDocument($this->sourcePath, $this->targetPath, 'en', 'de');
}
API Key Exposure:
.env or hardcode keys. Use Laravel's config() or environment variables.config/deepl.php:
'auth_key' => env('DEEPL_AUTH_KEY', throw new RuntimeException('DeepL key not set.')),
Character Limits:
billedCharacters in TextResult.if ($result->billedCharacters > 100000) {
Log::warning('High character usage: ' . $result->billedCharacters);
}
Document Size Limits:
minification for large files (e.g., PPTX):
$client->translateDocument($path, $outputPath, 'en', 'de', ['minification' => true]);
Rate Limiting:
use Symfony\Component\Process\Exception\TimeoutException;
try {
$result = $client->translateText(...);
} catch (\DeepL\RateLimitException $e) {
sleep(10); // Wait 10 seconds
retry();
}
Language Pair Availability:
formality or custom_instructions. Check DeepL’s docs first.$options = ['formality' => 'more'];
if (!$client->isLanguagePairSupported('en', 'de', $options)) {
unset($options['formality']);
}
XML/HTML Tag Handling:
tag_handling requires careful configuration. Test with simple inputs first:
$options = [
'tag_handling' => 'html',
'tag_handling_version' => 'v2',
];
Enable Verbose Logging:
$client = new DeepLClient($authKey, [
'verbose' => true,
'logger' => new \Monolog\Logger('deepl'),
]);
Inspect Raw API Responses:
$client->getHttpClient()->setHandler(new \GuzzleHttp\HandlerStack([
new \GuzzleHttp\Middleware::tap(function ($request, $next) {
Log::debug('DeepL Request:', [$request->getUri(), $request->getBody()]);
return $next($request);
}),
]));
Handle Document Translation Errors:
DocumentTranslationException to clean up partial uploads:
try {
$client->translateDocument($source, $target, 'en', 'de');
} catch (\DeepL\DocumentTranslationException $e) {
if ($e->documentHandle) {
$client->deleteDocument($e->documentHandle->documentId);
}
}
Custom Response Transformers:
DeepLClient to format responses for your API:
class CustomDeepLClient extends DeepLClient
{
public function translateAndFormat($text, $targetLang)
{
$result = parent::translateText($text, null, $targetLang);
return [
'translation' => $result->text,
'source_lang' => $result->detectedSourceLang,
'meta' => [
'characters' => $result->billedCharacters,
'model' => $result->modelTypeUsed,
],
];
}
}
Batch Processing Middleware:
$client->translateText($batch, null, 'fr', [
'preprocess' => function ($text) {
return str_replace(['...', '...'], '', $text); // Clean text
},
'postprocess' => function ($result) {
return strtoupper($result->text); // Capitalize
},
]);
Translation Memory Integration:
translation_memory_id to enforce brand consistency:
$options = [
'translation_memory_id' => 'your_memory_id',
'translation_memory_threshold' => 85,
];
Fallback Mechanisms:
How can I help you explore Laravel packages today?