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

Common Laravel Package

tencentcloud/common

tencentcloud/common provides shared foundation code for Tencent Cloud PHP SDK packages, including request signing, HTTP transport, credential handling, and common exceptions. Add it when integrating Tencent Cloud APIs or building service-specific clients in PHP.

View on GitHub
Deep Wiki
Context7

Getting Started

tencentcloud/common is the transport core of the Tencent Cloud PHP SDK, not a usable SDK by itself. It ships credentials, request signing (TC3-HMAC-SHA256), the cURL connection layer, AbstractClient, AbstractModel, and TencentCloudSDKException. Every generated product client (CvmClient, SmsClient, CdnClient, …) extends AbstractClient from this package.

Because it has essentially no direct dependents and a single star, treat it as an internal dependency: you almost never composer require tencentcloud/common alone. You require the monolith (tencentcloud/tencentcloud-sdk-php) or a per-product package, and common arrives transitively. Only pull it directly if you are writing your own generated client or a thin custom HTTP wrapper.

Setup

composer require tencentcloud/tencentcloud-sdk-php   # or a per-product package
php -m | grep curl                                   # ext-curl is not always declared
composer show tencentcloud/common                   # note the resolved version

Where to look first

  • src/Common/AbstractClient.php — the _request() pipeline, endpoint resolution, response model dispatch.
  • src/Common/Credential.php — secretId/secretKey/token.
  • src/Common/Profile/HttpProfile.php and ClientProfile.php — timeouts, endpoint, sign method, language.
  • src/Common/Exception/TencentCloudSDKException.php — getErrorCode(), getRequestId().
  • The generated *Request / *Response classes in the product package — these are your real API contract.

First use case: SMS verification codes

use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Sms\V20210111\SmsClient;
use TencentCloud\Sms\V20210111\Models\SendSmsRequest;

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

$http = new HttpProfile();
$http->setEndpoint('sms.tencentcloudapi.com');
$http->setProtocol('https');
$http->setConnectTimeout(5);
$http->setReqTimeout(15);

$profile = new ClientProfile();
$profile->setHttpProfile($http);
$profile->setSignMethod('TC3-HMAC-SHA256');
$profile->setLanguage('en-US');           // readable error messages

$client = new SmsClient($credential, 'ap-guangzhou', $profile);

$req = new SendSmsRequest();
$req->SmsSdkAppId    = config('services.tencent.sms_app_id');
$req->SignName       = config('services.tencent.sms_sign');
$req->TemplateId     = '1234567';
$req->TemplateParamSet = ['483920'];
$req->PhoneNumberSet   = ['+8613800000000'];

$resp = $client->SendSms($req);

Namespace version segments (V20210111) and endpoint hosts vary per product — copy them from the generated client's docblock.

Implementation Patterns

Bind a configured client per service in a service provider. Don't scatter new Credential(...) across controllers.

// app/Providers/TencentServiceProvider.php
$this->app->singleton(SmsClient::class, function () {
    $cred = new Credential(config('services.tencent.secret_id'), config('services.tencent.secret_key'));
    $http = new HttpProfile();
    $http->setEndpoint(config('services.tencent.sms_endpoint'));
    $http->setConnectTimeout(config('services.tencent.connect_timeout', 5));
    $http->setReqTimeout(config('services.tencent.req_timeout', 15));
    $profile = new ClientProfile();
    $profile->setHttpProfile($http);
    $profile->setSignMethod('TC3-HMAC-SHA256');
    $profile->setLanguage('en-US');
    return new SmsClient($cred, config('services.tencent.region'), $profile);
});

Keep secrets in config/services.php (which reads env), never env() directly in the closure — config:cache will otherwise hand you null.

Wrap every product client behind your own interface. AbstractClient methods are concrete and the response models are plain public-property bags, so mocking them in tests is painful. A one-method SmsSender interface with a real and a fake implementation gives you a clean testing seam and a place to attach logging, retries, and metrics.

Use retry() for throttling, but only on safe codes. The SDK historically does not retry for you.

$resp = retry(3, fn () => $client->SendSms($req), 200, function ($e) {
    return $e instanceof TencentCloudSDKException
        && in_array($e->getErrorCode(), ['RequestLimitExceeded', 'InternalError'], true);
});

Never retry non-idempotent actions on ambiguous failures — a timeout may mean the SMS was already queued.

Hydrate request models from arrays when convenient. Generated request models take an optional params array in their constructor, so a DTO or validated form array can flow straight in — but confirm field names against the generated class rather than guessing.

Handle STS temporary credentials explicitly. Pass the token as the third Credential argument, cache it (Redis) with an expiry margin, and rotate it in a scheduled job. A stale token surfaces as AuthFailure.TokenFailure only at call time.

For queue jobs, make SDK timeouts strictly smaller than the worker timeout (connect 5s, req 15s, $timeout = 30), otherwise a hung cURL call takes the worker down with it. Also set $tries and use release() with backoff on RequestLimitExceeded.

Log RequestId on every failure. Tencent support will ask for it, and it's the only way to correlate with their side.

catch (TencentCloudSDKException $e) {
    Log::warning('tencent.api.failed', [
        'code' => $e->getErrorCode(),
        'request_id' => $e->getRequestId(),
        'msg' => $e->getMessage(),
    ]);
}

Poll for async operations deliberately. Many Describe*/*Status APIs are eventually consistent. Poll with a bounded loop and exponential sleep, not a tight while.

Gotchas and Tips

  • Version drift between common and generated clients is the #1 breakage. Product packages pin a compatible common; a loose constraint plus a fresh composer update can yield signature errors or Class not found on response models. Pin exact versions together in composer.json and upgrade them as a set.
  • AbstractClient::_request() derives the response class from the action name (FooRequest → FooResponse). If you subclass or wrap manually and the naming doesn't line up, you get a confusing class-not-found rather than an API error.
  • An unset endpoint fails oddly. If you forget HttpProfile::setEndpoint(), you may get an empty host or a generic client-side exception rather than "endpoint missing." Always set it explicitly per product; don't try to share one HttpProfile across services.
  • HttpProfile / ClientProfile are mutable and are stored on the client. Don't reuse one instance across multiple clients in a long-running process — copy the settings instead.
  • Response models expose public properties, not getters. $resp->TotalCount, not $resp->getTotalCount(). Nested lists may come back as plain arrays or as hydrated models depending on the resolved SDK version — dd($resp->toJsonString()) once per new API and code against what you actually see.
  • Unset vs. null vs. empty matters. A property you never assign is generally omitted from the serialized payload; assigning '' or 0 sends it. Half the "MissingParameter" errors are a typo'd property name on a request model — the SDK silently ignores unknown keys.
  • Signature errors are usually clock skew or a swapped key. AuthFailure.SignatureFailure after a server migration → check NTP. AuthFailure.SignatureExpire → the box is minutes off, not the key.
  • RequestLimitExceeded is per-action and per-region, not a global quota. Fanning out a thousand DescribeInstances calls from one queue worker will throttle you regardless of how many workers you add.
  • Proxy and CA issues masquerade as API errors. Behind a corporate proxy or with a stale CA bundle you get generic connection exceptions; verify with curl -v https://<endpoint>/ before touching credentials.
  • The old qcloud/Qcloud\ SDK namespace can coexist with TencentCloud\Common\ if some legacy package is still installed. composer why tencentcloud/common will reveal duplicates; remove the legacy package rather than trying to bridge them.
  • Set ClientProfile::setLanguage('en-US'). Error messages default to Chinese, which is fine for logs but slows down debugging at 2am.
  • Never dump the Credential object into logs or an exception handler payload — the secret key and token are private properties, but var_export/print_r of a surrounding client object can still leak them.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin