S3 基础知识
Amazon Simple Storage Service (Amazon S3)
是一项面向 Internet 的存储服务。您可以通过 Amazon S3 随时在 Web 上的任何位置存储和检索的任意大小的数据。您可以通过 AWS 管理控制台这一简单直观的 Web 界面来完成这些任务。本指南将向您介绍 Amazon S3 以及如何使用 AWS 管理控制台来完成下图中所示的任务。
基础概念:Amazon S3 将数据存储为存储桶中的对象。对象由文件和描述该文件的任何可选元数据组成。
存储桶:数据都是存储在AWS 的存储桶中,我们可以把桶理解为磁盘分区,不过它是由一个桶名(字符串)唯一标识,即你不能创建别人已经创建过的桶。
对象: 对象键 (或键名称) 在存储桶中唯一地标识对象。(Key), 可以简单理解为存储的数据。
基础开发资源
- 示例代码和库
https://aws.amazon.com/code/Amazon-S3
。 - 教程
https://aws.amazon.com/articles/Amazon-S3
基础操作
// 添加开发工具包
composer require aws/aws-sdk-php
// 导入类
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
// 连接验证,实例化基础类
$key = 'KEY';
$secret = 'SECRET';
$credentials = new Aws\Credentials\Credentials($key, $secret);
// var_dump($credentials);exit;
// ap-southeast-1 新加坡
//Create a S3Client
$s3Client = new Aws\S3\S3Client([
'region' => 'ap-southeast-1', // 区域
'version' => '2006-03-01', // 版本
'credentials' => $credentials, // 验证
]);
桶操作
- 创建和使用 aws s3 存储桶
// 使用 ListBuckets 返回已经过身份验证的请求发件人所拥有的存储桶列表。
// 使用 CreateBucket 创建新存储桶。
// 使用 PutObject 向存储桶添加对象
//Listing all S3 Bucket
$buckets = $s3Client->listBuckets();
foreach ($buckets['Buckets'] as $bucket) {
echo $bucket['Name'] . "\n";
}
//Creating S3 Bucket
try {
$result = $s3Client->createBucket([
'Bucket' => $BUCKET_NAME,
]);
} catch (AwsException $e) {
// output error message if fails
echo $e->getMessage();
echo "\n";
}
// putObject to Bucket
try {
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'SourceFile' => $file_Path,
]);
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
- 管理桶权限
// 使用 GetBucketAcl 获取存储桶的访问控制策略。
// 使用 PutBucketAcl 通过 ACL 设置存储桶权限。
// Gets the access control policy for a bucket
$bucket = 'my-s3-bucket';
try {
$resp = $s3Client->getBucketAcl([
'Bucket' => $bucket
]);
echo "Succeed in retrieving bucket ACL as follows: \n";
var_dump($resp);
} catch (AwsException $e) {
// output error message if fails
echo $e->getMessage();
echo "\n";
}
// Sets the permissions on a bucket using access control lists (ACL).
$params = [
'ACL' => 'public-read',
'AccessControlPolicy' => [
// Information can be retrieved from `getBucketAcl` response
'Grants' => [
[
'Grantee' => [
'DisplayName' => '<string>',
'EmailAddress' => '<string>',
'ID' => '<string>',
'Type' => 'CanonicalUser',
'URI' => '<string>',
],
'Permission' => 'FULL_CONTROL',
],
// ...
],
'Owner' => [
'DisplayName' => '<string>',
'ID' => '<string>',
],
],
'Bucket' => $bucket,
];
try {
$resp = $s3Client->putBucketAcl($params);
echo "Succeed in setting bucket ACL.\n";
} catch (AwsException $e) {
// Display error message
echo $e->getMessage();
echo "\n";
}
- 配置 aws s3 存储桶
// 跨源资源共享 (CORS) 定义了在一个域中加载的客户端 Web 应用程序与另一个域中的资源交互的方式。Amazon S3 中的 CORS 支持让您可以使用 Amazon S3 构建丰富的客户端 Web 应用程序,同时让您可以选择性地允许跨源访问您的 Amazon S3 资源。
// 使用 GetBucketCors 获取存储桶的 CORS 配置。
// 使用 PutBucketCors 设置用于存储桶的 CORS 配置。
// Get CORS setting
try {
$result = $client->getBucketCors([
'Bucket' => $bucketName, // REQUIRED
]);
var_dump($result);
} catch (AwsException $e) {
// output error message if fails
error_log($e->getMessage());
}
// Set CORS setting
$result = $client->putBucketCors([
'Bucket' => $bucketName, // REQUIRED
'CORSConfiguration' => [ // REQUIRED
'CORSRules' => [ // REQUIRED
[
'AllowedHeaders' => ['Authorization'],
'AllowedMethods' => ['POST', 'GET', 'PUT'], // REQUIRED
'AllowedOrigins' => ['*'], // REQUIRED
'ExposeHeaders' => [],
'MaxAgeSeconds' => 3000
],
],
]
]);
var_dump($result);
} catch (AwsException $e) {
// output error message if fails
error_log($e->getMessage());
}
- 使用 aws s3 存储桶策略
// 使用 GetBucketPolicy 返回用于指定存储桶的策略。
// 使用 PutBucketPolicy 替换存储桶策略。
// 使用 DeleteBucketPolicy 从存储桶中删除策略。
// Get the policy of a specific bucket
try {
$resp = $s3Client->getBucketPolicy([
'Bucket' => $bucket
]);
echo "Succeed in receiving bucket policy:\n";
echo $resp->get('Policy');
echo "\n";
} catch (AwsException $e) {
// Display error message
echo $e->getMessage();
echo "\n";
}
// Replaces a policy on the bucket
try {
$resp = $s3Client->putBucketPolicy([
'Bucket' => $bucket,
'Policy' => 'foo policy',
]);
echo "Succeed in put a policy on bucket: " . $bucket . "\n";
} catch (AwsException $e) {
// Display error message
echo $e->getMessage();
echo "\n";
}
// Deletes the policy from the bucket
try {
$resp = $s3Client->deleteBucketPolicy([
'Bucket' => $bucket
]);
echo "Succeed in deleting policy of bucket: " . $bucket . "\n";
} catch (AwsException $e) {
// Display error message
echo $e->getMessage();
echo "\n";
}
文件操作
// upload file 基础上传
try {
$result = $s3Client->putObject([
'Bucket' => $bucketName,
'Key' => $key,
'Body' => fopen($file_Path, 'r')
]);
echo $result->get('ObjectURL');
} catch (Aws\S3\Exception\S3Exception $e) {
echo "There was an error uploading the file.\n";
echo $e->getMessage();
}
// 分段上传
$uploader = new MultipartUploader($s3Client, $file_Path, [
'bucket' => 'jh-test-four',
'key' => $key,
]);
do {
try {
$result = $uploader->upload();
} catch (MultipartUploadException $e) {
/**
* 作为源传递到 MultipartUploader 的流在上传之前不会自动倒回。
* 如果您在与上个示例类似的循环中使用流,而不是文件路径,则需要重置 $source 块中的 catch 变量。
*/
// rewind($file_Path);
$uploader = new MultipartUploader($s3Client, $file_Path, [
'state' => $e->getState(),
]);
}
} while (!isset($result));
// 文件下载
$result = $s3Client->getObject([
'Bucket' => $bucketName,
'Key' => $key,
]);
$length = $result['@metadata']['headers']['content-length'];
$this->downloadFile($result, $key, $length);
} catch (Aws\S3\Exception\S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
private function downloadFile($result, $key, $length)
{
$ua = $_SERVER['HTTP_USER_AGENT'];
$key = str_replace("+", "%20", urlencode($key));
header('Content-Description: File Transfer');
header("Content-Type: ".$result['ContentType']);
// header('Content-Disposition: attachment; filename='.$key);
header('Pragma: cache');
header('Cache-Control: public, must-revalidate, max-age=0');
header("Content-Length: ".$length);
header("Content-Transfer-Encoding: binary");
// 不同浏览器不同处理方式
if (preg_match("/MSIE/", $ua)) {
header('Content-Disposition: attachment; filename="' . $key . '"');
} else if (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8\'\'' . $key . '"');
} else{
header('Content-Disposition: attachment; filename="' . $key . '"');
}
echo $result['Body'];
}
以上满足基础操作,深入请参考文档
.