企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
今天 Q 群有朋友说不会 OSS 直传,那我就来写个例子吧。欢迎兄弟们探讨交流。 # 0. 引入 aws 的 sdk ~~~shell composer require aws/aws-sdk-php ~~~ # 1. 上传到阿里云OSS ## 1.1 创建S3客户端 ~~~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', ]); ~~~ ## 1.2 服务器上传文件 通常前端先上传到服务器,然后通过服务器再上传到OSS,即中传了一次。 ~~~php 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', ]); } ~~~ ## 1.3 前端直传文件到OSS ### 1.3.1 服务器先生成签名表单 ~~~php 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`就是前端需要的表单属性和表单输入,然后用于前端进行构造表单并提交即可。 ## 1.3.2 前端直接上传文件 我这里不采用JS(通常会是axios)来构造表单,而是用 PHP 的 guzzle client 来模拟前端实现。 ~~~php 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\. 上传到腾讯云COS ## 2.1 创建S3客户端 ~~~php $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, ]); ~~~ 服务器上传文件同上阿里云。 ## 2.2 前端直接上传文件 ### 2.2.1 服务器先生成签名表单 ~~~php 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]; } ~~~ ### 2.2.2 前端直接上传文件 ~~~php 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 ~