Amazon Web Services (AWS) 简单存储服务 (S3) 是一种高度可扩展的对象存储服务,可从网络上任何位置存储和检索任何大小或类型的数据。AWS S3 具有广泛的用途,包括托管文件供公共访问、存储敏感数据以及为应用程序提供持久存储。
在 AWS S3 中,每个数据项都被视为一个对象,这些对象被组织在称为存储桶的容器中。存储桶充当有效存储和管理对象的逻辑容器。AWS S3 提供了一系列功能,允许您对这些对象执行操作,例如创建新对象、读取其内容、更新其属性或在不再需要时删除它们。
AWS S3 的一个令人兴奋的方面是它与多种编程语言和平台兼容。在本文中,我们将深入探讨如何通过 PHP 客户端利用 AWS S3 的强大功能。
安装适用于 PHP 的 AWS 开发工具包
要开始使用适用于 PHP 的 AWS 开发工具包,请确保您的开发环境已满足以下先决条件:
PHP 版本 5.3.3 或更高版本,并已编译 CuRL 扩展。 Composer 包管理器。
强烈建议使用 Composer
安装适用于 PHP 的 AWS 开发工具包,因为它比手动获取源代码更简单。
要使用 Composer
安装 SDK,请运行以下命令:
composer require aws/aws-sdk-php
官方包存储库可在以下位置找到:
https://packagist.org/packages/aws/aws-sdk-php
不要忘记在您的项目中包含 Composer
依赖项 vendor/autoload.php
设置客户端
要使用 S3 客户端,您需要使用您的 AWS 凭据对其进行初始化。
// 使用您的 AWS 凭据设置 S3 客户端
$client = new S3Client([
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => [
'key' => AWS_KEY,
'secret' => AWS_SECRET,
],
]);
存储桶操作
要使用 S3 客户端执行基本的 S3 存储桶操作,您需要使用 $client
变量。以下代码片段演示了如何实现此目的:
创建存储桶:
该 createBucket()
方法用于创建新的 S3 存储桶。它需要指定存储桶的名称。
$client->createBucket(['Bucket' => $bucketName,]);
将对象上传到存储桶:
该 putObject()
方法用于将对象(文件或数据)上传到指定的 S3 存储桶。它需要指定存储桶的名称、对象的名称和对象的内容。
$client->putObject([ 'Bucket' => $bucketName, 'Key' => $objectKey, 'Body' => $objectContent,]);
获取客户端中的所有存储桶:
要检索与 S3 客户端关联的所有存储桶的列表,请使用listBuckets
方法。
$buckets = $client->listBuckets();
// $buckets 结果可以采用以下格式:
Array (
[0] => Array (
[Name] => example-bucket-1
[CreationDate] => DateTime Object ( /* Creation date and time */ )
)
[1] => Array (
[Name] => example-bucket-2
[CreationDate] => DateTime Object ( /* Creation date and time */ )
)
// 如果有其他储存桶
)
返回值是一个数组,其中每个元素对应一个存储桶。数组元素包含存储桶的名称和创建日期。
对象分页、过滤和选择
Amazon S3 是一个对象存储服务,而不是文件系统。存储桶包含对象,而不是文件和目录。这些对象按其键的字母顺序列出。
AWS S3 SDK 中提供了一个重要的方法 listObjectsV2()
,它允许您对 S3 存储桶中的对象进行分页、过滤和选择。下面详细介绍该方法的用法并对所涉及的基本参数进行解释。
// 调用 `listObjectsV2()` 方法
$objects = $client->listObjectsV2($listObjectsParams);
Bucket
参数是必需参数,指定 S3 存储桶的名称。
<?php
// 必需参数
$listObjectsParams = [
'Bucket' => 'YOUR_BUCKET_NAME',
];
?>
您还可以根据需要包含其他参数来过滤对象:
<?php
// 'Delimiter'用于分组对象键的字符
$listObjectsParams['Delimiter'] = '/';
// 'Prefix'指定对象键必须具有的前缀
$listObjectsParams['Prefix'] = '/GENRE_FOLDER/2026';
//‘StartAfter’ 指定对象键必须在指定对象键之后
$listObjectsParams['StartAfter'] = '/GENRE_FOLDER/2026/GENRE_SONG_2.mp3';
//‘MaxKeys’限制返回的对象数
$listObjectsParams['MaxKeys'] = '20';
?>
结果采用以下格式:
$objects = $client->listObjectsV2($listObjectsParams);
// result
$objects = {
Contents:[ { Key: '/GENRE_FOLDER/2026/GENRE_SONG_3.mp3' } ],
CommonPrefixes: [ { Prefix: '/GENRE_FOLDER/2026' } ],
Name: 'example',
Prefix: '',
MaxKeys: 20,
Delimiter: '/',
IsTruncated: false
}
Amazon S3 不是文件系统,但可以通过使用适当的参数来模拟文件系统行为
可以单独使用以下函数:
// 返回对象键的前缀作为文件夹名称
function getFolderNames($objects)
{
$folderNames = [];
foreach ($objects['CommonPrefixes'] ?? [] as $cp) {
$folderNames[] = $cp['Prefix'];
}
return $folderNames;
}
// 返回对象的总大小
function getSize($objects)
{
$totalSize = 0;
foreach ($objects as $object) {
$totalSize += $object['Size'];
}
return $totalSize;
}
生成预签名 URL 访问 S3 存储桶文件夹
预签名 URL 是带有编码签名的 URL,允许在有限时间内访问指定资源。
在 PHP 中,您可以使用适用于 PHP 的 AWS 开发工具包轻松生成这些 URL。
以下是生成用于下载 AWS S3 对象的预签名 URL 的函数示例:
function getObjectDownloadURL($client, $bucketName, $objectKey, $objectName)
{
$cmd = $client->getCommand('GetObject', [
'Bucket' => $bucketName,
'Key' => $objectKey,
'ResponseContentDisposition' => urlencode("attachment; filename=$objectName"),
]);
$request = $client->createPresignedRequest($cmd, '+7 days');
$url = (string) $request->getUri();
return $url;
}
// 返回从对象返回的预签名 URL 数组
function getObjectsDownloadURLs($client, $objects, $filterParams)
{
try {
$filterByText = $filterParams["ByText"] ?? "";
$filterByMaxKeys = $filterParams["ByMaxKeys"] ?? "";
// 对过滤文本进行转义
$filterByText = htmlspecialchars($filterByText, ENT_QUOTES, 'UTF-8');
$objectIndex = 0;
$urlsAsync = [];
// 遍历对象并根据条件进行过滤
foreach ($objects['Contents'] as $object) {
$objectKey = $object['Key'];
// 跳过目录和隐藏文件
if (substr($objectKey, -1) === '/' || substr(strrchr($objectKey, '/'), 1, 1) === '.') {
continue;
}
$tmp = explode('/', $objectKey);
$objectName = end($tmp);
// 跳过与过滤文本不匹配的对象
if (!stripos($objectName, $filterByText) !== false) {
continue;
}
$objectIndex++;
// 跳过超过指定最大值的对象
if ($objectIndex < 0 || $objectIndex > $filterByMaxKeys) {
continue;
}
// 为对象生成预签名 URL
$cmd = $client->getCommand('GetObject', [
'Bucket' => $bucketName,
'Key' => $objectKey,
'ResponseContentDisposition' => urlencode("attachment; filename=$objectName"),
]);
$request = $client->createPresignedRequest($cmd, '+7 days');
$urlValue = (string) $request->getUri();
$url = [$urlValue, $objectKey];
$urlsAsync[] = $url;
}
// 返回预签名 URL 数组
return $urlsAsync;
} catch (AwsException $e) {
// 在发生异常时返回 null
return null;
}
}
此 PHP 代码段利用 AWS 开发工具包创建安全的预签名 URL,允许用户在有限的时间内从 AWS S3 存储桶下载对象。您可以自定义 ResponseContentDisposition
选项来指定下载对象的文件名。此外,您可以灵活地调整到期日期,如下所示:
$request = $client->createPresignedRequest($cmd, '+2 weeks');
从 AWS 存储桶中压缩 S3 对象
由于 AWS S3 不是文件系统,因此它不提供将对象压缩并返回为 zip 的功能。但是,您可以使用本机 ZipArchive
类将对象的预签名 URL 下载到压缩的 zip 中。
以下是使用 ZipArchive
类将 S3 对象压缩到 zip 文件的示例代码:
function downloadAndCompressUrls($urls, $zipFileName)
{
// 创建新的 ZipArchive 实例
$zip = new ZipArchive();
// 打开 zip 文件以进行写入
if ($zip->open($zipFileName, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
return null; // 无法打开 zip 文件
}
try {
// 循环下载每个 URL 并将其添加到 zip 文件中
foreach ($urls as $url) {
// 尝试下载文件内容
$fileContent = @file_get_contents($url[0]);
// 如果下载成功,则将文件添加到 zip 存档中,并使用 URL 中派生的名称
if ($fileContent !== false) {
$zip->addFromString(basename($url[1]), $fileContent);
}
}
// 关闭 zip 存档
$zip->close();
// 返回创建的 zip 文件的路径
return $zipFileName;
} catch (Exception $e) {
// 处理异常(例如下载或添加文件失败)
return null;
}
}
配置跨域资源共享 (CORS)
跨域资源共享 (CORS) 是一种机制,允许 Web 应用程序从与其不相同的域请求资源。在 S3 存储桶中配置 CORS 设置允许您控制允许哪些 Web 域访问您的 S3 资源。
以下是 CORS 配置 JSON 的示例:
{
"CORSRules": [
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET"],
"AllowedOrigins": ["https://locahost:8000"]
}
]
}
您可以使用这些属性来控制允许哪些 Web 域访问您的 S3 资源以及它们可以如何访问这些资源。