はじめに
AWS S3(Simple Storage Service)を使ったことがない、またはエンジニア歴の浅い方向けに書いています。私自身、最初にS3に触れたときは用語や概念に戸惑ったので、同じように悩んでいる方の助けになればと思います。
ほとんど公式ドキュメントをなぞっているだけなので、読み慣れている方は最下部にまとめている参考ソースから飛んでもらうのが良いかもしれません。
S3って何?初心者向け解説
S3は、AWSが提供するファイル保存サービスです。画像、動画、テキストファイルなど、あらゆるファイルを保存できます。従来のファイルサーバーと比べて、以下のメリットがあります:
- サーバーの管理が不要
- 容量の制限がほぼない
- 世界中からアクセス可能
- 高い耐久性(ファイルが失われにくい)
初めてのS3は「バケット」と「オブジェクト」という言葉から戸惑うかもしれませんが、イメージとしては:
- バケット = フォルダ(または大きな箱)
- オブジェクト = ファイル
と考えるとわかりやすいと思います。
目次
S3をPHPで使うための準備
1. AWSアカウントの作成
まだAWSアカウントを持っていない場合は、AWSの公式サイトからアカウントを作成しましょう。クレジットカードが必要ですが、S3は使った分だけ課金されるので、小規模な利用なら月額数百円程度です。
2. PHP用のAWS SDKをインストール
Composerを使ってインストールするのが最も簡単です:
composer require aws/aws-sdk-php
3. 認証情報の設定
AWS SDKが正しく動作するためには、認証情報(アクセスキーとシークレットキー)が必要です。開発環境では以下の方法がおすすめです:
AWSコンソールでキーを発行する
- AWSコンソールにログイン
- 右上のアカウント名 → 「セキュリティ認証情報」を選択
- 「アクセスキー」セクションで「新しいアクセスキーの作成」を選択
- 表示されたキーをメモ(このページを閉じると二度とシークレットキーは表示されないので注意!)
認証情報を設定ファイルに保存
# AWS CLIをインストールしていれば、以下のコマンドで設定できます
aws configure
# 以下の情報を入力
AWS Access Key ID: (発行したアクセスキー)
AWS Secret Access Key: (発行したシークレットキー)
Default region name: ap-northeast-1 (東京リージョン)
Default output format: json
これで ~/.aws/credentials
ファイルに認証情報が保存されます。
ファイルのアップロード方法
さて、実際にファイルをアップロードしてみましょう。まずは一番シンプルな例から:
<?php
// AWS SDKを読み込む
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
// S3クライアントを作成
$s3 = new S3Client([
'region' => 'ap-northeast-1', // 東京リージョン
'version' => 'latest'
]);
try {
// ファイルをアップロード
$result = $s3->putObject([
'Bucket' => 'my-first-bucket', // バケット名(実際のバケット名に変更してください)
'Key' => 'my-first-file.txt', // S3上でのファイル名
'Body' => 'Hello World!これが最初のS3ファイルです', // ファイルの中身
]);
// 成功したらURLを表示
echo "ファイルのURL: " . $result['ObjectURL'] . "\n";
} catch (AwsException $e) {
// エラーが発生した場合
echo "エラー: " . $e->getMessage() . "\n";
}
ローカルファイルをアップロードする場合
既存のファイルをアップロードしたい場合は、SourceFile
パラメータを使います:
$result = $s3->putObject([
'Bucket' => 'my-first-bucket',
'Key' => 'images/profile.jpg',
'SourceFile' => '/path/to/local/profile.jpg', // ローカルのファイルパス
]);
ファイルのダウンロード方法
S3からファイルをダウンロードするコードも見てみましょう:
<?php
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
$s3 = new S3Client([
'region' => 'ap-northeast-1',
'version' => 'latest'
]);
try {
// ファイルを取得
$result = $s3->getObject([
'Bucket' => 'my-first-bucket',
'Key' => 'my-first-file.txt',
]);
// ファイルの内容を取得
$body = $result['Body'];
// 内容を表示
echo "ファイルの内容: " . $body . "\n";
// またはファイルとして保存
// file_put_contents('downloaded-file.txt', $body);
} catch (AwsException $e) {
echo "エラー: " . $e->getMessage() . "\n";
}
大きいファイルの場合
大きなファイルをダウンロードするときは、メモリを節約するために少しずつ読み込むと良いです:
$result = $s3->getObject([
'Bucket' => 'my-first-bucket',
'Key' => 'large-file.zip',
]);
$body = $result['Body'];
$body->rewind(); // ストリームの先頭に移動
// 保存先のファイルを開く
$handle = fopen('downloaded-large-file.zip', 'w');
// 少しずつ読み込んで書き込む
while (!$body->eof()) {
fwrite($handle, $body->read(1024)); // 1KBずつ読み込む
}
fclose($handle);
echo "ダウンロード完了!\n";
ここで使っている rewind()
は、ストリームの読み取り位置を先頭に戻す関数です。これにより、確実にファイルの最初から読み取ることができます。
ファイルのコピー活用例
S3の便利な機能の一つが、サーバーを経由せずにファイルをコピーできることです。実際の活用例を見てみましょう:
例1:開発環境から本番環境へのファイル移動
開発用のバケットから本番用のバケットへのコピー:
// 開発環境から本番環境へファイルをコピー
$s3->copyObject([
'Bucket' => 'production-bucket', // コピー先のバケット
'Key' => 'images/logo.png', // コピー先のパス/ファイル名
'CopySource' => 'dev-bucket/images/logo.png', // コピー元のバケット/パス/ファイル名
]);
echo "ファイルを本番環境にコピーしました!\n";
例2:バックアップの作成
重要なファイルのバックアップ作成:
// ファイル名に日付を追加してバックアップを作成
$date = date('Y-m-d');
$s3->copyObject([
'Bucket' => 'my-bucket',
'Key' => "backups/config-{$date}.json", // 日付付きのファイル名
'CopySource' => 'my-bucket/config.json',
]);
echo "設定ファイルのバックアップを作成しました!\n";
例3:画像のサイズ違いを作成
元画像から異なるサイズのバージョンを作成(実際のリサイズはサーバー側で行う必要があります):
// 元画像をアップロード
$s3->putObject([
'Bucket' => 'my-bucket',
'Key' => 'original/photo.jpg',
'SourceFile' => '/path/to/photo.jpg',
]);
// リサイズした画像をアップロード(この例ではリサイズ処理は省略)
$s3->putObject([
'Bucket' => 'my-bucket',
'Key' => 'thumbnails/photo.jpg',
'SourceFile' => '/path/to/resized_photo.jpg',
]);
echo "オリジナルと縮小版の両方をアップロードしました!\n";
初心者がハマりやすいポイント
ここからは、初めてS3を使う際に多くの方がつまずくポイントを紹介します。
1. バケット名の制約
バケット名には厳しい制約があります:
- 小文字、数字、ハイフンのみ使用可能
- 3~63文字の長さ
- 世界中で一意(他の誰かが使っている名前は使えない!)
以下のようなバケット名は避けましょう:
-
My-Bucket
(大文字は使えない) -
bucket_name
(アンダースコアは使えない) -
ab
(短すぎる) -
123.456.789.0
(IPアドレスのような形式は不可)
良い例:
my-first-bucket-123
company-app-logs-2025
2. リージョンの選択
バケットを作成するときに「リージョン」を選びます。
- 東京リージョン(ap-northeast-1):日本国内のユーザー向けのサービスなら、東京リージョンがおすすめです。
- バージニア北部(us-east-1):グローバルサービスの場合は、このリージョンが一般的です。
リージョンは後から変更できないので、よく考えて選びましょう!
3. 公開設定の理解
S3のファイルは、デフォルトでは非公開です。Webサイトで画像を表示するなど、公開したい場合は以下のような設定が必要です:
// 公開設定でファイルをアップロード
$s3->putObject([
'Bucket' => 'my-bucket',
'Key' => 'public/logo.png',
'SourceFile' => '/path/to/logo.png',
'ACL' => 'public-read', // ここで公開設定
]);
ただし、最近のAWSではバケットの設定によってはACL
が機能しないこともあります。その場合はバケットポリシーの設定が必要になります。
4. パス(キー)の階層構造
S3にはフォルダという概念はなく、すべてはキー(パス)によって表現されます:
images/avatars/user123.jpg
これは「フォルダ」ではなく、単に「/」を含む長いキー名です。ただし、S3のコンソールではフォルダのように見えます。
セキュリティの基本
1. 認証情報を守る
アクセスキーとシークレットキーは、あなたのAWSアカウントへの「鍵」です。以下のことを絶対に避けてください:
- GitHubなどの公開リポジトリにキーを含めること
- ソースコードに直接キーを書くこと
- 共有サーバーにキーをそのまま保存すること
代わりに:
- 環境変数を使う
- AWS IAMロールを使う(EC2やLambdaなど)
- 共有認証情報ファイル(~/.aws/credentials)を使う
2. 暗号化を使う
機密データを保存する場合は、暗号化を有効にしましょう:
// サーバーサイド暗号化を有効にしてアップロード
$s3->putObject([
'Bucket' => 'my-secure-bucket',
'Key' => 'confidential/data.txt',
'Body' => '機密情報です',
'ServerSideEncryption' => 'AES256', // 暗号化を有効に
]);
3. バケットポリシーの理解
バケットポリシーは、S3バケットへのアクセス権限を細かく制御するためのJSONドキュメントです。最初は複雑に感じるかもしれませんが、基本的な例を見てみましょう:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-public-bucket/public/*"
}
]
}
この例では、my-public-bucket
のpublic/
フォルダ内のすべてのファイルを誰でも読めるようにしています。
便利な使い方のヒント
1. 画像のアップロード
画像や他のバイナリファイルをアップロードするときは、ContentTypeを正しく設定しましょう:
$s3->putObject([
'Bucket' => 'my-bucket',
'Key' => 'images/photo.jpg',
'SourceFile' => '/path/to/photo.jpg',
'ContentType' => 'image/jpeg', // 正しいMIMEタイプを設定
]);
これにより、ブラウザでアクセスしたときに正しく表示されます。
2. 一時的なURL(署名付きURL)の生成
一定時間だけアクセスできるURLを生成できます。非公開ファイルをダウンロードさせたい場合に便利です:
// 1時間有効な署名付きURLを作成
$cmd = $s3->getCommand('GetObject', [
'Bucket' => 'my-private-bucket',
'Key' => 'confidential/report.pdf'
]);
// 60分(3600秒)有効なURLを生成
$request = $s3->createPresignedRequest($cmd, '+60 minutes');
$presignedUrl = (string) $request->getUri();
echo "この一時的なURLでダウンロードできます: " . $presignedUrl;
// この一時的なURLでダウンロードできます: https://my-private-bucket.s3.ap-northeast-1.amazonaws.com/confidential/report.pdf?X-Amz-Algorithm=...
3. キーのプレフィックスを使ったファイル一覧の取得
特定のフォルダ内のファイルを一覧表示したい場合:
// images/フォルダ内のファイルを一覧表示
$result = $s3->listObjects([
'Bucket' => 'my-bucket',
'Prefix' => 'images/', // 「images/」で始まるキーのみを取得
]);
echo "ファイル一覧:\n";
foreach ($result['Contents'] as $object) {
echo "- " . $object['Key'] . " (サイズ: " . $object['Size'] . " バイト)\n";
}
まとめ
この記事では、AWS S3を初めて使う方向けに、PHPでのS3操作方法を紹介しました。
非常に便利で最初に触るのに適しているツールだと思っています。
- ファイルのアップロード、ダウンロード、コピーの基本を押さえる
- セキュリティ(認証情報の管理、暗号化)を意識する
- バケット名やキー名は計画的に設計する
参考リソース
- AWS SDKfor PHP 公式ドキュメント
- Amazon S3 初心者ガイド
- AWS 料金計算ツール(S3の使用コストの見積もりに便利)