今天 Q 群有朋友说不会 OSS 直传,那我就来写个例子吧。欢迎兄弟们探讨交流。
composer require aws/aws-sdk-php
$s3client = new \Aws\S3\S3Client([
'credentials' => [
'key' => 'KEY',
'secret' => 'SK',
],
'region' => 'oss-cn-chengdu',
'version' => '2006-03-01',
'endpoint' => 'https://caylof.oss-cn-chengdu.aliyuncs.com',
'use_path_style_endpoint' => true,
// 'endpoint' => 'https://oss-cn-chengdu.aliyuncs.com',
// 'addressing_style' => 'virtual',
]);
通常前端先上传到服务器,然后通过服务器再上传到OSS,即中传了一次。
function put(\Aws\S3\S3Client $s3client): void
{
$bucket = 'a';
$key = '123.txt';
$s3client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'Body' => file_get_contents(__DIR__.'/1.php'),
'ContentType' => 'text/plain',
]);
}
function buildForm(\Aws\S3\S3Client $s3client): array
{
$bucket = 'a/123.txt'; // 这里阿云的兼容似乎有点别扭,用真正的bucket会有问题
$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;
// print_r($formAttributes);
// print_r($formInputs);
return [$formAttributes, $formInputs];
}
返回的 $formAttributes
和 $formAttributes
就是前端需要的表单属性和表单输入,然后用于前端进行构造表单并提交即可。
我这里不采用JS(通常会是axios)来构造表单,而是用 PHP 的 guzzle client 来模拟前端实现。
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());
}
$s3client = new \Aws\S3\S3Client([
'credentials' => [
'key' => 'KEY',
'secret' => 'SK',
],
'region' => 'auto',
'version' => 'latest',
'endpoint' => 'https://xxx-yyy.cos.ap-chengdu.myqcloud.com',
'use_path_style_endpoint' => true,
]);
服务器上传文件同上阿里云。
function buildForm(\Aws\S3\S3Client $s3client): array
{
$bucket = 'xxx-yyy'; // 这里腾讯云看起来比阿里云做的合理
$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;
// print_r($formAttributes);
// print_r($formInputs);
return [$formAttributes, $formInputs];
}
function uploadMock(array $formAttributes, array $formInputs): void
{
$multipart = [];
foreach ($formInputs as $name => $value) {
$multipart[] = [
'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());
}
~ over ~
aws不是亚马逊的包吗?
国内的云存储厂商基本上都支持 AWS S3 对象存储协议,S3 成为了云存储事实上的标准。