1. パッケージのインストール
まず、S3を使用するために必要な aws/aws-sdk-php
パッケージがインストールされているか確認します。インストールされていない場合は以下のコマンドで追加します。
composer require league/flysystem-aws-s3-v
2. AWS設定の追加
config/filesystems.php
にS3設定を追加します。env
関数で環境変数から情報を読み込むよう設定すると、管理がしやすくなります。
config/filesystems.php
// おそらく大体の場合はすでに書いてあるので、変更不要。
// 以下、envから読み込むので、自分の環境に合わせて書き換えなくて大丈夫です。
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
],
.env
// ここは自分の環境に合わせて書き換え
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=your_region
AWS_BUCKET=your_bucket_name
AWS_URL=https://your_bucket_name.s3.amazonaws.com
3. 画像のアップロード処理
ファイルのアップロードをコントローラで実行する方法を示します。
ここではユーザー情報にプロフィール画像をアップロードするという設定で実装方法を記述しています。
UserController.php
// UserController
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class UserController extends Controller
{
// 新規追加の保存
public function store(Request $request)
{
$request->validate([
'name' => ['required', 'string', 'max:100'],
'profile_image' => ['nullable', 'image', 'mimes:jpeg,png,jpg,gif', 'max:2048'],
]);
// 画像のアップロード
$profileImagePath = null;
if ($request->hasFile('profile_image')) {
// ファイルをS3にアップロード
$profileImagePath = $request->file('profile_image')->store('profile_images', 's3');
// アップロードしたファイルのアクセスを制限する(デフォルトでprivate)
Storage::disk('s3')->setVisibility($profileImagePath, 'private');
}
$user = User::create([
'name' => $request->first_name." ".$request->last_name,
'profile_image' => $profileImagePath,
]);
return redirect()->route('admin.users.index')->with('success', '作成されました。');
}
}
create.blade.php
<form action="{{ route('admin.users.store') }}" method="POST" enctype="multipart/form-data">
<div class="mb-3">
<label for="last_name" class="form-label">last_name</label>
<input type="text" class="form-control" id="last_name" name="last_name" value="{{ old('last_name') }}" required>
</div>
<div class="mb-3">
<label for="profile_image" class="form-label">プロフィール画像</label>
<input type="file" class="form-control" id="profile_image" name="profile_image">
</div>
<div class="pt-3">
<button type="submit" class="btn btn-primary">新規作成</button>
</div>
</form>
4. 画像の表示
S3に保存した画像を表示するには、S3のURLをそのままHTMLの画像タグなどに埋め込むことができます。
大体の場合は、セキュリティの観点からアクセス可能な時間を設定すると思います。その場合は、以下のようにModels内に書いておくと楽です。
Models/User.php
use Illuminate\Support\Facades\Storage;
class User extends Authenticatable
{
// s3 署名付きURLを取得するメソッド
public function getFileUrl($filePath)
{
if ($filePath) {
return Storage::disk('s3')->temporaryUrl(
$filePath, now()->addMinutes(15)
);
}
return null;
}
}
Bladeテンプレートでの表示例
// s3 署名付きURLを取得するメソッドを使う
@if ($user->profile_image )
<img src="{{ $user->getFileUrl($user->profile_image) }}" alt="Profile Image" class="">
@else
<span>画像なし</span>
@endif
前提として、AWSのS3にアクセス可能なIAMユーザーのアクセスキーとシークレットキーが設定されていることを想定しています。