如何使用 php 和 Amazon S3 sdk 下载文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7389394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:36:02  来源:igfitidea点击:

How do I download a file with php and the Amazon S3 sdk?

phpamazon-s3

提问by doremi

I'm trying to make it so that my script will show test.jpg in an Amazon S3 bucket through php. Here's what I have so far:

我正在尝试让我的脚本通过 php 在 Amazon S3 存储桶中显示 test.jpg。这是我到目前为止所拥有的:

require_once('library/AWS/sdk.class.php');

$s3 = new AmazonS3($key, $secret);

$objInfo = $s3->get_object_headers('my_bucket', 'test.jpg');
$obj = $s3->get_object('my_bucket', 'test.jpg', array('headers' => array('content-disposition' => $objInfo->header['_info']['content_type'])));

echo $obj->body;

This just dumps out the file data on the page. I think I need to also send the content-disposition header, which I thought was being done in the get_object() method, but it isn't.

这只是转储页面上的文件数据。我想我还需要发送 content-disposition 标头,我认为这是在 get_object() 方法中完成的,但事实并非如此。

Note: I'm using the SDK available here: http://aws.amazon.com/sdkforphp/

注意:我正在使用此处提供的 SDK:http: //aws.amazon.com/sdkforphp/

采纳答案by doremi

Got it to work by echo'ing out the content-type header before echo'ing the $object body.

通过在回显 $object 主体之前回显内容类型标头来使其工作。

$objInfo = $s3->get_object_headers('my_bucket', 'test.jpg');
$obj = $s3->get_object('my_bucket', 'test.jpg');

header('Content-type: ' . $objInfo->header['_info']['content_type']);
echo $obj->body;

回答by Maximus

Both of these methods work for me. The first way seems more concise.

这两种方法都适合我。第一种方式看起来更简洁。

    $command = $s3->getCommand('GetObject', array(
       'Bucket' => 'bucket_name',
       'Key'    => 'object_name_in_s3'  
       'ResponseContentDisposition' => 'attachment; filename="'.$my_file_name.'"'
    ));

    $signedUrl = $command->createPresignedUrl('+15 minutes');
    echo $signedUrl;
    header('Location: '.$signedUrl);
    die();

Or a more wordy but still functional way.

或者更冗长但仍然实用的方式。

    $object = $s3->getObject(array(
    'Bucket' => 'bucket_name',
    'Key'    => 'object_name_in_s3'   
    ));

    header('Content-Description: File Transfer');
    //this assumes content type is set when uploading the file.
    header('Content-Type: ' . $object->ContentType);
    header('Content-Disposition: attachment; filename=' . $my_file_name);
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');

    //send file to browser for download. 
    echo $object->body;

回答by Raj Sharma

For PHP sdk3 change the last line of Maximus answer

对于 PHP sdk3 更改 Maximus 答案的最后一行

    $object = $s3->getObject(array(
       'Bucket' => 'bucket_name',
       'Key'    => 'object_name_in_s3'   
    ));

    header('Content-Description: File Transfer');
    //this assumes content type is set when uploading the file.
    header('Content-Type: ' . $object->ContentType);
    header('Content-Disposition: attachment; filename=' . $my_file_name);
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');

    //send file to browser for download. 
    echo $object["Body"];

回答by NateNjugush

If you're still looking for a relevant answer in 2019+, With AWS SDK for PHP 3.x and specifically '2006-03-01' with composer, the following worked for me

如果您仍在 2019 年以上寻找相关答案,使用适用于 PHP 3.x 的 AWS 开发工具包,特别是使用 Composer 的“2006-03-01”,以下内容对我有用


...

/**
 * Download a file
 * 
 * @param   string  $object_key
 * @param   string  $file_name
 * @return  void
 */
function download($object_key, $file_name = '') {
  if ( empty($file_name) ) {
    $file_name = basename($file_path);
  }
  $cmd = $s3->getCommand('GetObject', [
    'Bucket'                        => '<aws bucket name>',
    'Key'                           => $object_key,
    'ResponseContentDisposition'    => "attachment; filename=\"{$file_name}\"",
  ]);
  $signed_url = $s3->createPresignedRequest($cmd, '+15 minutes') // \GuzzleHttp\Psr7\Request
                ->getUri() // \GuzzleHttp\Psr7\Uri
                ->__toString();
  header("Location: {$signed_url}");
}
download('<object key here>', '<file name for download>');

NOTE: This is a solution for those who would want to avoid the issues that may arise from proxying the download through their servers by using a direct download link from AWS.

注意:这是一种解决方案,适用于希望避免使用 AWS 的直接下载链接通过其服务器代理下载时可能出现的问题。

回答by Haje

I added the Content-Disposition header to the getAuthenticatedUrl();

我将 Content-Disposition 标头添加到 getAuthenticatedUrl();

 // Example
 $timeOut = 3600; // in seconds
 $videoName = "whateveryoulike";
 $headers = array("response-content-disposition"=>"attachment");
 $downloadURL = $s3->getAuthenticatedUrl( FBM_S3_BUCKET, $videoName, FBM_S3_LIFETIME + $timeOut, true, true, $headers );

回答by Rick Mac Gillis

This script downloads all files in all directories on an S3 service, such as Amazon S3 or DigitalOcean spaces.

此脚本下载 S3 服务(例如 Amazon S3 或 DigitalOcean 空间)上所有目录中的所有文件。

  1. Configure your credentials (See the class constants and the code under the class)
  2. Run composer require aws/aws-sdk-php
  3. Assuming you saved this script to index.php, then run php index.phpin a console and let it rip!
  1. 配置您的凭据(请参阅类常量和类下的代码)
  2. composer require aws/aws-sdk-php
  3. 假设您将此脚本保存到 index.php,然后php index.php在控制台中运行并让它翻录!

Please note that I just wrote code to get the job done so I can close down my DO account. It does what I need it to, but there are several improvements I could have made to make it more extendable. Enjoy!

请注意,我只是编写了代码来完成工作,因此我可以关闭我的 DO 帐户。它可以满足我的需要,但我可以进行一些改进以使其更具可扩展性。享受!



<?php

require 'vendor/autoload.php';
use Aws\S3\S3Client;

class DOSpaces {

    // Find them at https://cloud.digitalocean.com/account/api/tokens
    const CREDENTIALS_API_KEY           = '';
    const CREDENTIALS_API_KEY_SECRET    = '';

    const CREDENTIALS_ENDPOINT          = 'https://nyc3.digitaloceanspaces.com';
    const CREDENTIALS_REGION            = 'us-east-1';
    const CREDENTIALS_BUCKET            = 'my-bucket-name';

    private $client = null;

    public function __construct(array $args = []) {

        $config = array_merge([
            'version' => 'latest',
            'region'  => static::CREDENTIALS_REGION,
            'endpoint' => static::CREDENTIALS_ENDPOINT,
            'credentials' => [
                'key'    => static::CREDENTIALS_API_KEY,
                'secret' => static::CREDENTIALS_API_KEY_SECRET,
            ],
        ], $args);

        $this->client = new S3Client($config);
    }

    public function download($destinationRoot) {
        $objects = $this->client->listObjectsV2([
            'Bucket' => static::CREDENTIALS_BUCKET,
        ]);

        foreach ($objects['Contents'] as $obj){

            echo "DOWNLOADING " . $obj['Key'] . "\n";
            $result = $this->client->getObject([
                'Bucket' => 'dragon-cloud-assets',
                'Key' => $obj['Key'],
            ]);

            $this->handleObject($destinationRoot . $obj['Key'], $result['Body']);

        }
    }

    private function handleObject($name, $data) {
        $this->ensureDirExists($name);

        if (substr($name, -1, 1) !== '/') {
            echo "CREATING " . $name . "\n";
            file_put_contents($name, $data);
        }
    }

    private function ensureDirExists($name) {
        $dir = $name;
        if (substr($name, -1, 1) !== '/') {
            $parts = explode('/', $name);
            array_pop($parts);
            $dir = implode('/', $parts);
        }

        @mkdir($dir, 0777, true);
    }

}

$doSpaces = new DOSpaces([
    'endpoint' => 'https://nyc2.digitaloceanspaces.com',
    'credentials' => [
        'key'    => '12345',
        'secret' => '54321',
    ],
]);
$doSpaces->download('/home/myusername/Downloads/directoryhere/');