この記事は PHP Advent Calendar 2021 16日目の記事です。
15日目の記事は@opyさん投稿の PHPによる疑似的なイミュータブルとムーブセマンティクスモドキ 、
17日目の記事は@iamyukihiroさん投稿の私用のLinuxサーバーに、PHPのビルトインサーバーをデプロイした話です。
本記事の概要
AWS SDK for PHP を用いて S3 の指定バケットへ画像アップロードをできるようにします。
- AWS アカウント
を所持している前提で進めていきます。
1. 導入
今回使用するライブラリを導入します。
AWS SDK for PHP の導入
参考:Installing the AWS SDK for PHP Version 3 - AWS SDK for PHP
導入方法はいくつかありますが、今回はオーソドックスに Composer を使います。
やり方は簡単で、プロジェクトのベースディレクトリ内で
composer require aws/aws-sdk-php
コマンドを実行するだけです。
実行後、
composer show -i
等で表示されるパッケージ一覧の中に aws/aws-sdk-php
が追加されていれば成功です。
phpdotenv の導入
環境変数設定のライブラリです。
後述するコードにて、phpdotenv を使用しているので、
未導入の方は
composer require vlucas/phpdotenv
にてライブラリ追加をしてください。
2. S3 にバケットを作る
バケットを作成します。
AWS マネジメントコンソールログイン後、S3を開き、バケット作成をします。
ここではバケット名を php-advent2021-sdk-upload
としています。
一意な名前が必要なので「被っているよ!!」と怒られたら、別の名前を設定しましょう。
リージョンは何処でも大丈夫ですが、どのリージョンを設定したか覚えておいて下さい。
その他設定はデフォルトで大丈夫です。
確認ができたら作成しましょう。
3. AWS にアクセスするための鍵情報を取得
参考:IAM ユーザーのアクセスキーの管理 - AWS Identity and Access Management
S3 に接続できるようにするため、
- アクセスキー ID
- シークレットアクセスキー
の2つが必要です。
セキュリティ認証情報画面を開き、**アクセスキー (アクセスキー ID とシークレットアクセスキー)**セクションを開きます。
新しいアクセスキーの作成を行った後、キーファイルのダウンロードをします。
rootkey.csv
というファイルがダウンロードできるので、
ファイルを開いてアクセスキー IDとシークレットアクセスキー情報を確認しましょう。
env ファイルの作成
上記のアクセス情報を記述した .env
ファイルを作成し、プロジェクトのディレクトリ内に配置しておきましょう。
AWS_ACCESS_KEY_ID="XXXXXXXXXXXXXXXXXXXX"
AWS_SECRET_ACCESS_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
AWS_ACCESS_KEY_ID
に アクセスキー ID
AWS_SECRET_ACCESS_KEY
に シークレットアクセスキー
の情報を記述します。
4. 実装
参考:Creating and Using Amazon S3 Buckets with the AWS SDK for PHP Version 3 - AWS SDK for PHP
以下、実際のコードです。
<?php
require './vendor/autoload.php';
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();
function main()
{
$credentials = [
'key' => $_ENV['AWS_ACCESS_KEY_ID'],
'secret' => $_ENV['AWS_SECRET_ACCESS_KEY'],
];
$bucket = 'php-advent2021-sdk-upload';
$srcFilePath = 'ソースファイルのディレクトリパスをここに記述';
$extension = pathinfo($srcFilePath, PATHINFO_EXTENSION);
$key = 'test' . '.' . $extension;
try {
$s3Client = new S3Client([
'region' => 'ap-northeast-1',
'version' => '2006-03-01',
'credentials' => $credentials,
]);
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'SourceFile' => $srcFilePath,
]);
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
}
main();
$bucket
には自身で作成したバケット名、
$srcFilePath
にはアップロードしたい画像ファイルのディレクトリパスを記述してください。
解説
必須のコードブロックは2つです。
S3 への接続
$s3Client = new S3Client([
'region' => 'ap-northeast-1',
'version' => '2006-03-01',
'credentials' => $credentials,
]);
region
はバケットを生成したリージョンを記述します。
version
ではバージョン指定をします。バージョニング設定を有効化している場合以外はこのままで大丈夫です。
credentials
には アクセスキー ID と シークレットアクセスキー を入れます。
S3 バケットへのアップロード
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'SourceFile' => $srcFilePath,
]);
Bucket
にはアップロードするバケット名を記述します。
Key
はバケット以下のファイルパス及びファイル名を設定します。
そのままでは拡張子なしのファイルがアップロードされてしまうので、 pathinfo で拡張子を取得し $extension
に格納するようにしています。
SourceFile
にはアップロードするファイルの絶対パスを指定します。
実行すると、S3のバケットへ画像がアップロードされました。
まとめ
本記事のコードを応用すれば
**「クライアントから画像のパスが POST されたらアップロードする」**ような API も実現出来るので
是非活用してみてください。
ちなみに、この設定のままではアップロードした画像をブラウザで確認することができません。
S3 バケットの**「ブロックパブリックアクセス設定」を適切に設定する**必要がありますのでご注意ください。
(デフォルトではパブリックアクセスがブロックされます)
画像の確認に関しては読み取り専用アクセス許可を付与すれば大丈夫です。
※要望が多ければこの辺りについて詳しくまとめようと思います。