こんにちは、いつもお読みいただきありがとうございます。
Ken(@gootablog)です。
PHPでS3にファイルをアップロードしたりダウンロードしたりするやり方はどうやるの?
ということで今回はこのやり方を書いていきたいと思います。
前提
すでに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
になっていれば削除されています。
最後に
使う前は複雑で難しそうなイメージでしたが、実際に使ってみると簡単な動作なら割りとサクッとできてしまうので使いやすいです。
ぜひ試してみてください。