

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

# 适用于 PHP 的 Amazon SDK 版本 3 的亚马逊 S3 预签名网址
<a name="s3-presigned-url"></a>

您可以通过传递请求信息作为查询字符串参数，而不是使用授权 HTTP 标头来验证特定类型的请求。这在允许第三方浏览器直接访问您的私有 Amazon S3 数据，而无需代理请求时非常有用。其概念是构造一个“预签名”的请求并将其编码为另一个用户可以使用的 URL。此外，您还可以通过指定过期时间来限制预签名请求。

## 为 HTTP GET 请求创建预签名 URL
<a name="s3-presigned-url-get"></a>

以下代码示例演示了如何使用适用于 PHP 的 SDK 为 HTTP GET 请求创建预签名 URL。

```
<?php

require 'vendor/autoload.php';

use Aws\S3\S3Client;

$s3Client = new S3Client([
    'region' => 'us-west-2',
]);

// Supply a CommandInterface object and an expires parameter to the `createPresignedRequest` method.
$request = $s3Client->createPresignedRequest(
    $s3Client->getCommand('GetObject', [
        'Bucket' => 'amzn-s3-demo-bucket',
        'Key' => 'demo-key',
    ]),
    '+1 hour'
);

// From the resulting RequestInterface object, you can get the URL.
$presignedUrl = (string) $request->getUri();

echo $presignedUrl;
```

[`createPresignedRequest` 方法的 API 参考](https://docs.amazonaws.cn/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html#method_createPresignedRequest)提供了更多详细信息。

其他人可以在接下来的一个小时内使用 `$presignedUrl` 值来检索对象。当发出 HTTP GET 请求时（例如使用浏览器），在 S3 服务看来，该调用来自创建了预签名 URL 的用户。

## 为 HTTP PUT 请求创建预签名 URL
<a name="s3-presigned-url-put"></a>

以下代码示例演示了如何使用适用于 PHP 的 SDK 为 HTTP PUT 请求创建预签名 URL。

```
<?php

require 'vendor/autoload.php';

use Aws\S3\S3Client;

$s3Client = new S3Client([
    'region' => 'us-west-2',
]);

$request = $s3Client->createPresignedRequest(
    $s3Client->getCommand('PutObject', [
        'Bucket' => 'amzn-s3-demo-bucket',
        'Key' => 'demo-key',
    ]),
    '+1 hour'
);

// From the resulting RequestInterface object, you can get the URL.
$presignedUrl = (string) $request->getUri();
```

其他人现在可以在 HTTP PUT 请求中使用预签名 URL 来上传文件：

```
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;

// ...

function uploadWithPresignedUrl($presignedUrl, $filePath, $s3Client): ?Response
{
    // Get the HTTP handler from the S3 client.
    $handler = $s3Client->getHandlerList()->resolve();
    
    // Create a stream from the file.
    $fileStream = new Stream(fopen($filePath, 'r'));
    
    // Create the request.
    $request = new Request(
        'PUT',
        $presignedUrl,
        [
            'Content-Type' => mime_content_type($filePath),
            'Content-Length' => filesize($filePath)
        ],
        $fileStream
    );
    
    // Send the request using the handler.
    try {
        $promise = $handler($request, []);
        $response = $promise->wait();
        return $response;
    } catch (Exception $e) {
        echo "Error uploading file: " . $e->getMessage() . "\n";
        return null;
    }
}
```