【PHP】PHPでAWS S3に画像をアップロード・ダウンロードする方法

【PHP】PHPでAWS S3に画像をアップロード・ダウンロードする方法

PHP

公開: 2018-03-19

更新: 2020-04-29

こんにちは、いつもお読みいただきありがとうございます。
Ken(@gootablog)です。

PHPでS3にファイルをアップロードしたりダウンロードしたりするやり方はどうやるの?
ということで今回はこのやり方を書いていきたいと思います。

前提

すでにS3のバケットがあり、アクセスキーが生成されているという前提で書いていきます。
バケットを作成していなかったら「【AWS】S3のバケットを作ってみる」を参考に作成してみてください。

【AWS】S3のバケットを作ってみる

AWS SDK for PHP のインストール・下準備

まずはAWSのSDK(ソフトウェア開発キット)ファイルをインストールします。

※バージョンは2018年3月時点のもの

Composerを使用する場合

"require": {
    "aws/aws-sdk-php": "^3.52"
}

キー名がrequireとなっているところに"aws/aws-sdk-php": "^3.52"と記述してインストールコマンドを実行

$ composer install

or

$ composer update

コマンドから直接インストールする場合はこちらを実行してください。
最新のバージョンでインストールされます。

$ composer require aws/aws-sdk-php

composerのオートローダーファイルを読み込み、名前空間のエイリアスを定義します。
パスは適宜書き換えてください。

require '../../vendor/autoload.php';

use Aws\S3\S3Client;
use Aws\CommandPool;

そして、S3のオブジェクトを作成する際の情報を変数に格納しS3オブジェクトを作成して下準備完了です。

情報は、IAM作成時に生成されたアクセスキーとシークレットキー、バージョン、リージョン、バケットネームを書いておけば大丈夫です。必要あれば値を変えてみてください。


$credentials = [
    'key' => '*** Your access key ***',
    'secret' => '*** Your secret key ***',
];

$bucket_version = 'latest';
$bucket_region = 'ap-northeast-1';
$bucket_name = '*** bucket name ***';


$s3 = new S3Client([
    'credentials' => $credentials,
    'region'  => $bucket_region,
    'version' => $bucket_version,
]);

S3へアップロード

ではS3へアップロード方法を書いていきたいと思います。

putObjectというメソッドを使うことでアップロードができます。

KeyにはS3に保存するパスを指定し、SourceFileにはアップロードするファイルのパスを指定します。引数にそれらのパラーメーターを渡して実行するとuploadディレクトリのpath.jpgというファイルが、バケットのs3というディレクトリにsample.jpgというファイル名でアップロードされます。

$params = [
    'Bucket' => $bucket_name,
    'Key' => 's3/sample.jpg',
    'SourceFile'   => './upload/path.jpg',
];

try
{
    $result = $s3 -> putObject($params);
    var_dump($result['ObjectURL']);
}
catch(S3Exception $e)
{
    var_dump($e -> getMessage());
}

複数枚同時にアップロードをしたい場合はこのように書いてください。

$commands[] = $s3 -> getCommand('PutObject', $params);

try
{
    $results = CommandPool::batch($s3, $commands);
}
catch (CommandTransferException $e)
{
    $succeess = $e->getSuccessfulCommands();
    echo "Failed Commands:\n";
    foreach ($e->getFailedCommands() as $failedCommand) 
    {
        echo $e->getExceptionForFailedCommand($failedCommand)->getMessage() . "\n";
    }
}

実行したいメソッドとアップロードファイルなどを指定している$paramsを 引数にしてオ配列($commands)にしておき、CommandPool::batchというメソッドを使うことでまとめて実行することができます。
もし途中でエラーが発生した場合は実行に成功したものと失敗したもので分けて取得することができます。

S3からダウンロード

次はS3からファイルをダウンロードする方法です。

getObjectメソッドを使うことでダウンロードができます。
SaveAsというキーをパラメーターに追加すると指定した場所にファイルを保存できます。

返された値ですが、Bodyキーにファイルのデータが入っているので表示したり画像をダウンロードしたりできるので試してみてください。



$params = [
    'Bucket' => $bucket_name,
    'Key' => 's3/sample.jpg',
    // 'SaveAs' => './download/path.jpg', //ファイルとして保存する時に使用
];

try
{
    $result = $s3->getObject($params);

    $len = $result['ContentLength'];

    //ファイルを表示
    header("Content-Type: {$result['ContentType']}");
    echo $result['Body'];

    //ファイルダウンロード
    header('Content-Type: application/force-download;');
    header('Content-Length: '.$len);
    header('Content-Disposition: attachment; filename="sample.jpg"');
    echo $result['Body'];
}
catch(S3Exception $e)
{
    var_dump($e -> getMessage());
}   


複数のファイルをまとめて取得する方法はアップロードと同じやり方をするとできます。

$commands[] = $s3 -> getCommand('GetObject', $params);

try
{
    $results = CommandPool::batch($s3, $commands);
}
catch (CommandTransferException $e)
{
    $succeess = $e->getSuccessfulCommands();
    echo "Failed Commands:\n";
    foreach ($e->getFailedCommands() as $failedCommand) 
    {
        echo $e->getExceptionForFailedCommand($failedCommand)->getMessage() . "\n";
    }
}

S3のファイルのリンクを取得する

ファイルをダウンロードではなく、リンクを取得したい場合はこんな感じで書くと取得できます。

ここでは1分だけ公開するように設定してリンクを取得しています。

try
{
    $params = [
        'Bucket' => $bucket_name,
        'Key' => 's3/sample.jpg',
    ];

        $cmd = $s3 -> getCommand('GetObject', $obj_param);
        $request = $s3->createPresignedRequest($cmd, '+1 minutes');
        $uri = $request -> getUri();
        $url = $uri -> getScheme().'://'.$uri -> getHost().$uri -> getPath().'?'.$uri -> getQuery();
        var_dump($url);
    }


}
catch(S3Exception $e)
{
    var_dump($e -> getMessage());
}

S3のファイルを削除する

これまでと同様のやり方でメソッド名を変更するだけで削除できます。


$obj_param = [
    'Bucket' => $bucket_name,
    'Key' => 's3/sample.jpg',
];

try
{
    $result = $s3 -> deleteObject($obj_param);
    var_dump($result['DeleteMarker']);
}
catch(S3Exception $e)
{
    var_dump($e -> getMessage());
}

返されたオブジェクトのDeleteMarkerというキーがfalseになっていれば削除されています。

最後に

使う前は複雑で難しそうなイメージでしたが、実際に使ってみると簡単な動作なら割りとサクッとできてしまうので使いやすいです。

ぜひ試してみてください。