Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tmt Laravel Package

tencentcloud/tmt

Tencent Cloud TMT SDK for PHP provides a client for Tencent Cloud Machine Translation, enabling text translation, language detection, and related API calls from PHP applications. Install via Composer and configure credentials to integrate translation features into Laravel or other PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

tencentcloud/tmt is not a Laravel package — it's the per-product, machine-generated PHP client for Tencent Cloud's Machine Translation (TMT) API, version 20180321. There is no service provider, no facade, no publishable config, and 0 dependents because virtually everyone just installs the monolith (tencentcloud/tencentcloud-sdk-php) instead. Judge it by the API behind it: a stable, cheap, character-billed translation service.

composer require tencentcloud/tmt

Where to look first: src/TencentCloud/Tmt/V20180321/TmtClient.php is your real documentation — every public method is one API action (TextTranslate, TextTranslateBatch, ImageTranslate, SpeechTranslate, LanguageDetect). Each action has a matching Models/*Request and *Response class; the request setters are the parameter list and the response getters are the return shape, so you rarely need the web docs.

First use case — translating user-generated or admin-authored text (TextTranslate covers ~90% of usage):

// config/services.php
'tencent' => [
    'tmt' => [
        'secret_id'  => env('TENCENT_TMT_SECRET_ID'),
        'secret_key' => env('TENCENT_TMT_SECRET_KEY'),
        'region'     => env('TENCENT_TMT_REGION', 'ap-guangzhou'),
    ],
],
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Tmt\V20180321\TmtClient;
use TencentCloud\Tmt\V20180321\Models\TextTranslateRequest;

$credential = new Credential(
    config('services.tencent.tmt.secret_id'),
    config('services.tencent.tmt.secret_key')
);

$httpProfile = new HttpProfile();
$httpProfile->setEndpoint('tmt.tencentcloudapi.com');
$httpProfile->setReqTimeout(10);

$clientProfile = new ClientProfile();
$clientProfile->setHttpProfile($httpProfile);

$client = new TmtClient($credential, config('services.tencent.tmt.region'), $clientProfile);

$req = new TextTranslateRequest();
$req->setSourceText('Hello world');
$req->setSource('en');      // or 'auto'
$req->setTarget('zh');
$req->setProjectId(0);

$res = $client->TextTranslate($req);

$res->getTargetText(); // 你好世界
$res->getSource();     // source language (detected when 'auto')
$res->getRequestId();  // always log this

Create the API key as a CAM sub-user scoped to TMT actions only — never the root account key, and never commit it.

Implementation Patterns

Wrap it once, then never import it again. The generated classes are ugly and voluminous; keep them out of controllers and models.

interface Translator {
    public function translate(string $text, string $from, string $to): string;
}

final class TencentTranslator implements Translator { /* the block above */ }

Bind Translator and a lazy TmtClient singleton in AppServiceProvider:

$this->app->singleton(TmtClient::class, fn () => /* build with config() */);
$this->app->singleton(Translator::class, TencentTranslator::class);

The client is just credentials + profile objects — safe to reuse for the life of a request or queue worker, and building it lazily avoids paying for it on requests that never translate.

Cache-aside inside the adapter — the single biggest cost lever. Billing is per character, and the same input always yields the same output, so cache before calling and write back after:

$key = 'tmt:'.sha1("{$from}|{$to}|{$text}");
return Cache::remember($key, now()->addDays(90), fn () => $this->callApi($text, $from, $to));

Callers get caching for free and can't accidentally bypass it. Short-circuit empty/whitespace strings before the key lookup.

Batch aggressively, off the request cycle. TextTranslateBatch takes SourceTextList and returns a TargetTextList in the same order (check the current per-request item cap). Translating a page of 20 records as 20 HTTP calls is both slow and rate-limit bait. Push bulk work — backfilling a catalog, translating a newly imported CSV — into a queued job.

Translate on write, not on read. Store the translated copy alongside the source when content is saved, in a job. If you must translate on read (e.g. arbitrary user content), keep the timeout at 2–3s and serve the source text on failure — translation should degrade, not 500.

Centralize language mapping. Your app stores zh-Hans, pt_BR, en-GB; TMT wants zh, pt, en. Map in one place, and pin the source language whenever you know it — auto costs an extra detection pass and is less predictable for static UI strings.

Instrument for cost reconciliation. Log RequestId, source/target, mb_strlen of the input, latency, and cache hit/miss. Characters are the billing unit; a small tmt_usage table lets you reconcile against the Tencent console and spot runaway loops (a retranslation job re-firing every minute is a real incident).

Per-tenant quotas. On multi-tenant apps, put a counter/limiter in front of the adapter keyed by tenant. One customer's import loop shouldn't exhaust the shared account quota.

Testing: don't hit the network. Bind a fake Translator in the container for feature tests. To unit-test your adapter's mapping and chunking logic, inject TmtClient rather than new-ing it, and subclass/override TextTranslate in a test double — there is no SDK-provided fake.

Region is a config decision, not a constant. Pick the closest region that offers TMT; it affects latency and may affect data-residency obligations. Keep it in env, not in code.

Gotchas and Tips

  • Package vs monolith collision. tencentcloud/tmt is a per-product split of tencentcloud/tencentcloud-sdk-php. If anything else in the tree already pulls the monolith, you can end up with two copies of TencentCloud\Common\* and TencentCloud\Tmt\* — duplicate class definitions, autoload ambiguity, or version drift producing baffling "class not found"/"method not found" errors. Decide on one path (monolith-only is usually simpler) and pin it.
  • Errors are exceptions, not return codes. TencentCloudSDKException exposes getErrorCode(), getErrorMessage(), getRequestId(). Catch it at the adapter boundary, log the RequestId, and rethrow as your own exception type — never let the SDK's exception escape into a controller.
  • Retry narrowly. Retry transport failures and throttling-class codes only (RequestLimitExceeded-style), with exponential backoff plus jitter and a hard attempt cap. Never wrap the call in a naive for loop: each attempt is billed, and your usage log will drift from reality.
  • Clock skew breaks signing. Requests are TC3-HMAC-SHA256 signed; a container whose clock is minutes off gets signature-expired errors that look like credential problems. Check date before debugging code.
  • Per-request length limit. TextTranslate rejects very long strings (on the order of a couple thousand characters, language-dependent). Chunk on sentence boundaries with mb_* functions — byte-offset chunking splits multibyte characters and produces garbled output at the seams.
  • Nulls are real. Generated response getters return null for fields the API didn't populate. Convert to your own DTO immediately so the nullability is explicit and testable.
  • Unsupported language pairs fail loudly. An unknown or unsupported code returns a parameter error; there's no silent fallback. Validate against a whitelist you own before calling.
  • Don't send raw markup. HTML/Markdown passed directly gets its tag names and attributes translated too. Extract text nodes first and reassemble.
  • config:cache freezes env(). Read credentials via config('services.tencent.tmt.*') inside the app, or you'll get nulls in production only.
  • ProjectId defaults to 0. Set it explicitly; leaving it out is fine in most setups but some console-configured projects expect it.
  • Privacy is your problem, not the SDK's. You're shipping user text (possibly PII) to a third party. Decide policy, disclosure, and retention before enabling it on user-generated content — and note which regions/industries can't use it at all.
  • Extension points are thin. The only real seams are the client object itself and, version-dependent, Guzzle-level hooks like setHttpClient() / profile proxy settings. Don't subclass generated code; build the interface + adapter + fake and let the SDK be an implementation detail you can swap for another MT vendor later.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast