How to Directly Upload Files to Alibaba OSS and Tencent COS with PHP and AWS SDK
Learn step-by-step how to configure the AWS PHP SDK, generate signed forms on the server, and perform direct client uploads to Alibaba Cloud OSS and Tencent Cloud COS, including PHP code for server-side signing, multipart requests, and handling responses.
Install the AWS SDK for PHP
Install the SDK via Composer:
composer require aws/aws-sdk-php1. Upload to Alibaba Cloud OSS
1.1 Create an S3 client for OSS
$s3client = new \Aws\S3\S3Client([
'credentials' => [
'key' => 'YOUR_ACCESS_KEY',
'secret' => 'YOUR_SECRET_KEY',
],
'region' => 'oss-cn-chengdu',
'version' => '2006-03-01',
'endpoint'=> 'https://caylof.oss-cn-chengdu.aliyuncs.com',
'use_path_style_endpoint' => true,
]);1.2 Server‑side file upload
The application can upload a local file to OSS directly from the server:
function put(\Aws\S3\S3Client $s3client): void {
$bucket = 'your-bucket-name';
$key = '123.txt';
$s3client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'Body' => file_get_contents(__DIR__.'/1.php'),
'ContentType' => 'text/plain',
]);
}1.3 Front‑end direct upload to OSS
1.3.1 Generate a signed POST form on the server
The server creates a PostObjectV4 instance, which returns the HTML form attributes and hidden inputs required by the browser (or any HTTP client) to upload the file directly to OSS.
function buildForm(\Aws\S3\S3Client $s3client): array {
// Use a full object key as the bucket parameter to work around OSS compatibility quirks
$bucket = 'a/123.txt';
$key = 'a/123.txt';
$maxUploadSize = 1024 * 1024 * 10; // 10 MiB
$contentType = 'text/plain';
$formInputs = ['acl' => 'private'];
$options = [
['acl' => 'private'],
['bucket' => $bucket],
['key' => $key],
['Content-Type' => $contentType],
['content-length-range', 1, $maxUploadSize],
];
$expires = '+10 minutes';
$postObject = new \Aws\S3\PostObjectV4(
$s3client,
$bucket,
$formInputs,
$options,
$expires
);
$formAttributes = $postObject->getFormAttributes();
$formInputs = $postObject->getFormInputs();
$formInputs['key'] = $key;
$formInputs['Content-Type'] = $contentType;
return [$formAttributes, $formInputs];
}The returned $formAttributes contain the form's action URL and method, while $formInputs hold the hidden fields (e.g., policy, signature, key, acl). These values are sent unchanged by the client.
1.3.2 Simulate a browser upload with PHP (Guzzle)
The following function builds a multipart request that mimics a browser form submission. It is useful for testing or for server‑side proxy uploads.
function uploadMock(array $formAttributes, array $formInputs): void {
$multipart = [];
foreach ($formInputs as $name => $value) {
$multipart[] = [
'name' => $name,
'contents' => $value,
];
}
$multipart[] = [
'name' => 'file',
'contents' => file_get_contents(__DIR__.'/1.php'),
];
$http = new \GuzzleHttp\Client();
$resp = $http->put($formAttributes['action'], [
'multipart' => $multipart,
'headers' => ['Accept' => 'application/json'],
]);
echo $resp->getStatusCode() . PHP_EOL;
print_r($resp->getBody()->getContents());
}2. Upload to Tencent Cloud COS
2.1 Create an S3 client for COS
$s3client = new \Aws\S3\S3Client([
'credentials' => [
'key' => 'YOUR_ACCESS_KEY',
'secret' => 'YOUR_SECRET_KEY',
],
'region' => 'auto',
'version' => 'latest',
'endpoint'=> 'https://xxx-yyy.cos.ap-chengdu.myqcloud.com',
'use_path_style_endpoint' => true,
]);The server‑side upload code is identical to the OSS example; only the client configuration differs.
2.2 Front‑end direct upload to COS
2.2.1 Generate a signed POST form (COS version)
Cos uses a bucket name format that works out‑of‑the‑box. The code mirrors the OSS version, with the bucket name set to the COS bucket identifier.
function buildForm(\Aws\S3\S3Client $s3client): array {
$bucket = 'xxx-yyy'; // COS bucket identifier
$key = 'a/123.txt';
$maxUploadSize = 1024 * 1024 * 10;
$contentType = 'text/plain';
$formInputs = ['acl' => 'private'];
$options = [
['acl' => 'private'],
['bucket' => $bucket],
['key' => $key],
['Content-Type' => $contentType],
['content-length-range', 1, $maxUploadSize],
];
$expires = '+10 minutes';
$postObject = new \Aws\S3\PostObjectV4(
$s3client,
$bucket,
$formInputs,
$options,
$expires
);
$formAttributes = $postObject->getFormAttributes();
$formInputs = $postObject->getFormInputs();
$formInputs['key'] = $key;
$formInputs['Content-Type'] = $contentType;
return [$formAttributes, $formInputs];
}2.2.2 Simulate front‑end upload with Guzzle (COS header conversion)
Cos expects the signature‑related fields to be prefixed with X-Cos instead of X-Amz. The upload function rewrites the field names accordingly before sending the multipart request.
function uploadMock(array $formAttributes, array $formInputs): void {
$multipart = [];
foreach ($formInputs as $name => $value) {
$multipart[] = [
// Replace the AWS prefix with the COS prefix
'name' => str_replace('X-Amz', 'X-Cos', $name),
'contents' => $value,
];
}
$multipart[] = [
'name' => 'file',
'contents' => file_get_contents(__DIR__.'/1.php'),
];
$http = new \GuzzleHttp\Client();
$resp = $http->put($formAttributes['action'], [
'multipart' => $multipart,
'headers' => ['Accept' => 'application/json'],
]);
echo $resp->getStatusCode() . PHP_EOL;
print_r($resp->getBody()->getContents());
}Both Alibaba Cloud OSS and Tencent Cloud COS can be accessed using the same AWS SDK workflow: create a client, generate a signed POST policy on the server, and let the client upload files directly without routing the file through the application server.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
