human: 如何处理七牛云的对象存储AWS SDK for PHP

gpt: [对象存储](https://developer.qiniu.com/kodo) > 使用指南 >
[开发指南](https://developer.qiniu.com/kodo/development_guidelines/8596/development-
guidelines) > [AWS S3
兼容](https://developer.qiniu.com/kodo/development_guidelines/4086/aws-s3-compatible)
> [兼容 SDK 示例](https://developer.qiniu.com/kodo/development_guidelines/12553/S3
SDK sample) > AWS SDK for PHP

#  AWS SDK for PHP

最近更新时间: 2024-02-19 17:03:17

# 导入 AWS SDK for PHP

确保 PHP v5.5 或更新版本已经安装。

其他推荐配置

  * 使用 cURL 7.16.2 或更新版本
  * 使用 OPCache
  * 不使用 Xdebug
  * 使用 Composer 自动加载依赖
  * 详见：https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_requirements.html

添加 AWS SDK for PHP 包

    
    
    composer require aws/aws-sdk-php=3.281.15
    

对于之后的每个代码示例，将代码创建在 `main.php` 后，执行

    
    
    php main.php
    

即可执行代码。

# 对象上传

## 获取客户端上传 URL

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    $request = $s3Client->createPresignedRequest($s3Client->getCommand("GetObject", ["Bucket" => "<Bucket>", "Key" => "<Key>"]), "+1 hours");
    echo $request->getUri() . "\n";
    

这段代码将生成一个经过预先签名的客户端上传 URL，有效期为 1 小时，客户端可以在过期时间内对该 URL 发送 HTTP PUT 请求将文件上传。

以下是用 curl 上传文件的案例：

    
    
    curl -X PUT --upload-file "<path/to/file>" "<presigned url>"
    

## 服务器端直传

### 单请求上传（文件）

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $putObjectResponse = $s3Client->putObject(["Bucket" => "<Bucket>", "Key" => "<Key>", "SourceFile" => "<path/to/upload>"]);
        echo "ETag: " . $putObjectResponse["ETag"] . "\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

### 单请求上传（数据流）

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $putObjectResponse = $s3Client->putObject(["Bucket" => "<Bucket>", "Key" => "<Key>", "Body" => "Hello, Qiniu S3!"]);
        echo "ETag: " . $putObjectResponse["ETag"] . "\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

### 分片上传（文件）

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1",  // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    const PART_SIZE = 5 * 1024 * 1024; // 分片大小为 5 MB
    
    try {
        $createMultipartUploadResponse = $s3Client->createMultipartUpload(["Bucket" => "<Bucket>", "Key" => "<Key>"]);
        $file = fopen("<path/to/upload>", "rb");
        if (!$file) {
            return;
        }
        $parts = array();
        try {
            // 这里给出的案例是串行分片上传。可以自行改造成并行分片上传以进一步提升上传速度
            for ($partNumber = 1;; $partNumber++) {
                $partBody = fread($file, PART_SIZE);
                if (!$partBody) {
                    break;
                }
                $uploadPartResponse = $s3Client->uploadPart([
                    "Bucket" => $createMultipartUploadResponse["Bucket"],
                    "Key" => $createMultipartUploadResponse["Key"],
                    "UploadId" => $createMultipartUploadResponse["UploadId"],
                    "PartNumber" => $partNumber,
                    "Body" => $partBody,
                ]);
                array_push($parts, ["ETag" => $uploadPartResponse["ETag"], "PartNumber" => $partNumber]);
            }
        } finally {
            if (!$file) {
                fclose($file);
            }
        }
        $completeMultipartUploadResponse = $s3Client->completeMultipartUpload([
            "Bucket" => $createMultipartUploadResponse["Bucket"],
            "Key" => $createMultipartUploadResponse["Key"],
            "UploadId" => $createMultipartUploadResponse["UploadId"],
            "MultipartUpload" => [
                "Parts" => $parts,
            ]
        ]);
        echo 'ETag: ' . $completeMultipartUploadResponse["ETag"] . "\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

### 上传文件

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1",  // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    $file = fopen("<path/to/upload>", "r") or die("Unable to open file");
    try {
        $resp = $s3Client->upload("<Bucket>", "<Key>", $file);
        echo 'ETag: ' . $resp["ETag"] . "\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    } finally {
        fclose($file);
    }
    

### 上传目录

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $s3Client->uploadDirectory("<path/to/upload>", "<Bucket>", "<KeyPrefix>");
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

# 对象下载

## 获取客户端下载 URL

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    $request = $s3Client->createPresignedRequest($s3Client->getCommand("PutObject", ["Bucket" => "<Bucket>", "Key" => "<Key>"]), "+1 hours");
    echo $request->getUri() . "\n";
    

这段代码将生成一个经过预先签名的客户端下载 URL，有效期为 1 小时，客户端可以在过期时间内对该 URL 发送 HTTP GET 请求将文件下载。

以下是用 curl 下载文件的案例：

    
    
    curl -o "<path/to/download>" "<presigned url>"
    

## 服务器端直接下载

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $getObjectResponse = $s3Client->getObject(["Bucket" => "<Bucket>", "Key" => "<Key>", "SaveAs" => "<path/to/download>"]);
        echo "ETag: " . $getObjectResponse["ETag"] . "\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 下载目录

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $s3Client->downloadBucket("<path/to/download>", "<Bucket>", "<KeyPrefix>");
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

# 对象管理

## 获取对象信息

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $headObjectResponse = $s3Client->headObject(["Bucket" => "<Bucket>", "Key" => "<Key>"]);
        echo "ETag: " . $headObjectResponse["ETag"] . "\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 修改对象 MimeType

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $s3Client->copyObject([
            "Bucket" => "<Bucket>",
            "Key" => "<Key>",
            "MetadataDirective" => "REPLACE",
            "CopySource" => "/<Bucket>/<Key>",
            "ContentType" => "<NewContentType>",
        ]);
        echo "Done\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 修改对象存储类型

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $s3Client->copyObject([
            "Bucket" => "<Bucket>",
            "Key" => "<Key>",
            "MetadataDirective" => "REPLACE",
            "CopySource" => "/<Bucket>/<Key>",
            "StorageClass" => "GLACIER",
        ]);
        echo "Done\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 复制对象副本

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $s3Client->copyObject([
            "Bucket" => "<ToBucket>",
            "Key" => "<ToKey>",
            "MetadataDirective" => "COPY",
            "CopySource" => "/<FromBucket>/<FromKey>",
        ]);
        echo "Done\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 复制对象副本（大于 5GB）

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    const PART_SIZE = 5 * 1024 * 1024; // 分片大小为 5 MB
    
    try {
        $headObjectRequest = ["Bucket" => "<FromBucket>", "Key" => "<FromKey>"];
        $headObjectResponse = $s3Client->headObject($headObjectRequest);
        $createMultipartUploadResponse = $s3Client->createMultipartUpload(["Bucket" => "<ToBucket>", "Key" => "<ToKey>"]);
        $parts = array();
        $copied = 0;
        // 这里给出的案例是串行分片复制。可以自行改造成并行分片复制以进一步提升复制速度
        for ($partNumber = 1; $headObjectResponse["ContentLength"] > $copied; $partNumber++) {
            $partSize = min(PART_SIZE, $headObjectResponse["ContentLength"] - $copied);
            $uploadPartCopyResponse = $s3Client->uploadPartCopy([
                "Bucket" => $createMultipartUploadResponse["Bucket"],
                "Key" => $createMultipartUploadResponse["Key"],
                "UploadId" => $createMultipartUploadResponse["UploadId"],
                "PartNumber" => $partNumber,
                "CopySource" => "/" . $headObjectRequest["Bucket"] . "/" . $headObjectRequest["Key"],
                "CopySourceRange" => "bytes=" . $copied . "-" . ($copied + $partSize),
            ]);
            array_push($parts, ["ETag" => $uploadPartCopyResponse["CopyPartResult"]["ETag"], "PartNumber" => $partNumber]);
            $copied += $partSize;
        }
        $completeMultipartUploadResponse = $s3Client->completeMultipartUpload([
            "Bucket" => $createMultipartUploadResponse["Bucket"],
            "Key" => $createMultipartUploadResponse["Key"],
            "UploadId" => $createMultipartUploadResponse["UploadId"],
            "MultipartUpload" => [
                "Parts" => $parts,
            ]
        ]);
        echo 'ETag: ' . $completeMultipartUploadResponse["ETag"] . "\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 删除空间中的文件

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $s3Client->deleteObject(["Bucket" => "<Bucket>", "Key" => "<Key>"]);
        echo "Done\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 获取指定前缀的文件列表

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $listObjectsV2Response = $s3Client->listObjectsV2(["Bucket" => "<Bucket>", "Prefix" => "<KeyPrefix>"]);
        foreach ($listObjectsV2Response["Contents"] as $content) {
            echo "Key: " . $content["Key"] . "\n";
            echo "ETag: " . $content["ETag"] . "\n";
        }
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

## 批量删除空间中的文件

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $s3Client = new S3Client([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $s3Client->deleteObjects([
            "Bucket" => "<Bucket>",
            "Delete" => [
                "Objects" => [
                    ["Key" => "<Key1>"],
                    ["Key" => "<Key2>"],
                    ["Key" => "<Key3>"],
                ]
            ],
        ]);
        echo "Done\n";
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

# 临时安全凭证

创建 `main.php`

    
    
    <?php
    
    require 'vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\Sts\StsClient;
    use Aws\Credentials\Credentials;
    use Aws\Exception\AwsException;
    
    $stsClient = new StsClient([
        "region" => "cn-east-1", // 华东-浙江区 region id
        "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
        "credentials" => new Credentials("<QiniuAccessKey>", "<QiniuSecretKey>"),
    ]);
    
    try {
        $getFederationTokenResponse = $stsClient->getFederationToken([
            "Name" => "Bob",
            "Policy" => json_encode([
                "Version" => "2012-10-17",
                "Statement" => [
                    [
                        "Sid" => "Stmt1",
                        "Effect" => "Allow",
                        "Action" => ["*"],
                        "Resource" => ["*"],
                    ],
                ],
            ]),
            "DurationSeconds" => 3600,
        ]);
        $credentials = $getFederationTokenResponse["Credentials"];
        $s3Client = new S3Client([
            "region" => "cn-east-1", // 华东-浙江区 region id
            "endpoint" => "https://s3.cn-east-1.qiniucs.com",  // 华东-浙江区 endpoint
            "credentials" => new Credentials($credentials["AccessKeyId"], $credentials["SecretAccessKey"], $credentials["SessionToken"], $credentials["Expiration"]),
        ]);
        // 可以使用这些临时凭证调用 S3 服务
        $listBucketsResponse = $s3Client->listBuckets();
        foreach ($listBucketsResponse["Buckets"] as $bucket) {
            echo $bucket["Name"] . "\n";
        }
    } catch (AwsException $e) {
        echo "Error: " . $e . "\n";
    }
    

以上内容是否对您有帮助？