Amazon S3 Stream WrapperAmazon适 SDK for PHP 发工具包版本 3 - Amazon适用于 PHP 的开发工具包
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Amazon S3 Stream WrapperAmazon适 SDK for PHP 发工具包版本 3

Amazon S3 Stream Wrapper 支持您使用内置 PHP 函数从 Amazon S3 存储和检索数据,这些函数包括file_get_contentsfopencopyrenameunlinkmkdir, 和rmdir

您需要注册 Amazon S3 Stream Wrapper 才可使用。

$client = new Aws\S3\S3Client([/** options **/]); // Register the stream wrapper from an S3Client object $client->registerStreamWrapper();

这样您就可以使用 Amazon S3 中存储的存储桶和对象的s3://协议。Amazon S3 Stream Wrapper 接受包含存储桶名称的字符串,后跟正斜杠和可选的对象键或前缀:s3://<bucket>[/<key-or-prefix>]

注意

Stream Wrapper 可处理您至少拥有读取权限的对象和存储桶。这就意味着,您的用户应有权针对任何需要交互的存储桶执行 ListBucket,并针对任何需要交互的对象执行 GetObject。对于您不具有此级别权限的使用情形,建议您直接使用 Amazon S3 客户端操作。

下载数据

您可以使用 file_get_contents 获取对象内容。但使用此功能要小心,它会将对象的全部内容载入内存。

// Download the body of the "key" object in the "bucket" bucket $data = file_get_contents('s3://bucket/key');

使用fopen()如果处理较大文件或需要从 Amazon S3 流式传输数据,请留意。

// Open a stream in read-only mode if ($stream = fopen('s3://bucket/key', 'r')) { // While the stream is still open while (!feof($stream)) { // Read 1,024 bytes from the stream echo fread($stream, 1024); } // Be sure to close the stream resource when you're done with it fclose($stream); }
注意

只有调用 fflush 才会返回文件写入错误。如果调用了未刷新的 fclose,不会返回这些错误。如果 fclose 关闭了流,它的返回值将为 true;无论其内部 fflush 是否会响应任何错误。如果调用 file_put_contents 也不会返回这些错误,这是由于 PHP 的实施方式导致的。

打开可搜寻的流

以“r”模式打开的流仅允许读取流中的数据,默认情况下不可搜寻。这样数据才能够真正以流式处理的方式从 Amazon S3 下载,之前读取的字节不需要缓冲到内存中。如果需要对流进行搜寻,可以将 seekable 传递到函数的流上下文选项

$context = stream_context_create([ 's3' => ['seekable' => true] ]); if ($stream = fopen('s3://bucket/key', 'r', false, $context)) { // Read bytes from the stream fread($stream, 1024); // Seek back to the beginning of the stream fseek($stream, 0); // Read the same bytes that were previously read fread($stream, 1024); fclose($stream); }

“打开可搜寻的流”支持您搜寻之前读取的字节。您不可跳转到尚未从远程服务器读取的字节。要允许重新调用之前读取的数据,需使用流装饰器将数据缓冲到 PHP 临时流中。如果缓存数据量超过 2 MB,临时流中的数据会从内存传输到磁盘中。在 Amazon S3 下载大文件时,请留意这一点。seekable流上下文设置。

上传数据

您可以使用将数据上传到 Amazon S3file_put_contents()

file_put_contents('s3://bucket/key', 'Hello!');

您可以结合使用 fopen() 和“w”、“x”或“a”流访问模式来流式传输数据,从而上传较大的文件。Amazon S3 流包装器执行不是支持同时读取和写入流(例如 “r+”、“w+” 等)。这是因为 HTTP 协议不允许同时读取和写入。

$stream = fopen('s3://bucket/key', 'w'); fwrite($stream, 'Hello!'); fclose($stream);
注意

Amazon S3 需要在发送请求负载之前指定内容长度标题。因此,在 PutObject 操作中上传的数据会使用 PHP 临时流进行内部缓冲,直到流刷新或关闭。

注意

只有调用 fflush 才会返回文件写入错误。如果调用了未刷新的 fclose,不会返回这些错误。如果 fclose 关闭了流,它的返回值将为 true;无论其内部 fflush 是否会响应任何错误。如果调用 file_put_contents 也不会返回这些错误,这是由于 PHP 的实施方式导致的。

fopen 模式

PHP 的 fopen() 函数需要您指定 $mode 选项。mode 选项指定数据是否可在流中进行读写,以及打开流时文件是否必须存在。Amazon S3 Stream Wrapper 支持以下模式。

r

只读流,文件必须已存在。

w

只可写入的流。如果该文件已存在,则将覆盖该文件。

a

只可写入的流。如果文件已存在,则会将它下载到临时流中,并且对流的任何写入操作将追加到之前上传的数据后面。

x

只可写入的流。如果文件不存在将引发错误。

其他对象函数

Stream Wrappers 允许多种不同的内置 PHP 函数与 Amazon S3 这样的自定义系统配合使用。Amazon S3 Stream Wrapper 支持您针对 Amazon S3 中存储的对象执行以下函数。

unlink()

从存储桶中删除一个对象。

// Delete an object from a bucket unlink('s3://bucket/key');

您可以传递 DeleteObject 操作的任何可用选项,修改对象的删除方式 (例如指定具体的对象版本)。

// Delete a specific version of an object from a bucket unlink('s3://bucket/key', stream_context_create([ 's3' => ['VersionId' => '123'] ]);

filesize()

获取对象的大小。

// Get the Content-Length of an object $size = filesize('s3://bucket/key', );

is_file()

检查 URL 是否为文件。

if (is_file('s3://bucket/key')) { echo 'It is a file!'; }

file_exists()

检查某个对象是否存在。

if (file_exists('s3://bucket/key')) { echo 'It exists!'; }

filetype()

检查 URL 是否对应于文件或存储桶 (dir)。

file()

将对象内容加载到一些行中。您可以传递 GetObject 操作的任何可用选项,修改文件的下载方式。

filemtime()

获取对象的最新修改日期。

重命名()

复制对象并删除原始版本,从而对对象重命名。您可以将 CopyObjectDeleteObject 操作的可用选项传递到流上下文参数,修改复制和删除对象的方式。

注意

虽然copy一般与 Amazon S3 Stream Wrapper 配合使用,由于copy函数。我们建议您使用 AwsS3ObjectCopier 的实例作为替代。

使用 存储桶

您修改和浏览 Amazon S3 存储桶的方式,与 PHP 允许的在您的文件系统中进行修改和遍历目录的方式类似。

以下是创建存储桶的示例。

mkdir('s3://bucket');

您可以将流上下文选项传递到 mkdir() 方法,使用 CreateBucket 操作可用的参数修改存储桶的创建方式。

// Create a bucket in the EU (Ireland) Region mkdir('s3://bucket', stream_context_create([ 's3' => ['LocationConstraint' => 'eu-west-1'] ]);

您可以使用 rmdir() 函数删除存储桶。

// Delete a bucket rmdir('s3://bucket');
注意

只有空存储桶才可删除。

列出存储桶的内容

您可以将开放目录 ()再添加器 ()重排目录 (), 和闭幕镜 ()PHP 与 Amazon S3 流包装器一起运行,以遍历存储桶的内容。您可以将 ListObjects 操作的可用参数作为 opendir() 函数的自定义流上下文选项进行传递,以修改呈现对象的方式。

$dir = "s3://bucket/"; if (is_dir($dir) && ($dh = opendir($dir))) { while (($file = readdir($dh)) !== false) { echo "filename: {$file} : filetype: " . filetype($dir . $file) . "\n"; } closedir($dh); }

您可以使用 PHP 的 RecursiveDirectoryIterator 以递归方式列出存储桶中的每个对象和前缀。

$dir = 's3://bucket'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); foreach ($iterator as $file) { echo $file->getType() . ': ' . $file . "\n"; }

还可以使用 Aws\recursive_dir_iterator($path, $context = null) 函数以递归方式列出存储桶内容,这样可产生较少的 HTTP 请求。

<?php require 'vendor/autoload.php'; $iter = Aws\recursive_dir_iterator('s3://bucket/key'); foreach ($iter as $filename) { echo $filename . "\n"; }

流上下文选项

您可以通过传递自定义流上下文选项,自定义 Stream Wrapper 使用的客户端,或用于缓存之前加载的存储桶和键信息的缓存。

Stream Wrapper 针对每个操作支持以下流上下文选项。

client

Aws\AwsClientInterface 对象,用于执行命令。

cache

Aws\CacheInterface 的实例可用于缓存之前获得的文件统计数据。默认情况下,Stream Wrapper 使用内存中 LRU 缓存。