LaavelからAWS S3へ画像をアップロードする方法をまとめました。
前提条件
AWS S3でユーザ登録とバケットの作成ができていること。
※AWS S3の設定はRails, Laravel(画像アップロード)向けAWS(IAM:ユーザ, S3:バケット)の設定を参考にしてください
S3パッケージのインストール
パッケージはflysystem-aws-s3-v3を使用します。
以下を実行してインストールしてください。
composer require league/flysystem-aws-s3-v3
ファイルシステムの設定
/config/filesystems.php
を以下のように編集します。
'default' => env('FILESYSTEM_DRIVER', 'local'),
// 追記
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
// 〜 略 〜
'disks' => [
'local' => [
// 〜 略 〜
],
'public' => [
// 〜 略 〜
],
// 以下を追記
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
],
環境変数の設定
プロジェクト直下にある.env
ファイルを以下のように編集します。
AWS_ACCESS_KEY_ID='AWSで作成したAccess key ID'
AWS_SECRET_ACCESS_KEY='AWSで作成したSecret access key'
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET='作成したバケット名'
Laravelの実装
今回は単純にcreateアクションでS3へアップロードします。
最低限のコードは次節以降になります。
アップロード処理
テーブルの作成
まずはデータベースにアップロード用のテーブルを作成するために、マイグレーションファイルを作成します。
php artisan make:migration create_posts_table
作成したマイグレーションファイルを以下のように編集します。
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
// 画像のパスを保存するカラムを追加
$table->string('image_path')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
マイグレーションを実行します。
php artisan migrate
以上でテーブルの作成は完了です。
Model
対応するModelを作成します。
php artisan make:model Post
View
/resources/views/post/create.blade.php
を作成します。
作成したファイルを以下のように編集します。
@section('content')
<form action="{{ action('PostsController@create') }}" method="post" enctype="multipart/form-data">
<!-- アップロードフォームの作成 -->
<input type="file" name="image">
{{ csrf_field() }}
<input type="submit" value="アップロード">
</form>
@endsection
Controller
Controllerを作成します。
php artisan make:controller PostsController
作成したControllerを以下のように編集します。
<?php
// 略
use App\Post;
use Storage;
class PostsController extends Controller
{
public function add()
{
return view('posts.create');
}
public function create(Request $request)
{
$post = new Post;
$form = $request->all();
//s3アップロード開始
$image = $request->file('image');
// バケットの`myprefix`フォルダへアップロード
$path = Storage::disk('s3')->putFile('myprefix', $image, 'public');
// アップロードした画像のフルパスを取得
$post->image_path = Storage::disk('s3')->url($path);
$post->save();
return redirect('posts/create');
}
}
以上で、画像のアップロードは完成です。
実際にアップロードして、バケットへ画像がアップロードできていることを確認してください。
例:
画像の表示
ローカル画像を表示する場合とほとんど同じです。
View
/resources/views/post/index.blade.php
を作成し、以下のように修正します。
@section('content')
@foreach($posts as $post)
@if ($post->image_path)
<!-- 画像を表示 -->
<img src="{{ $post->image_path }}">
@endif
@endforeach
@endsection
Controller
Controllerに以下のようにindexアクションを追加します。
public function index(Request $request)
{
$posts = Post::all();
return view('posts.index', ['posts' => $posts]);
}
以上で、表示処理は完成です。
補足
うまく動作しない場合は、キャッシュをクリアしてみてください。
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
最後に
flysystem-aws-s3-v3
パッケージを使用することで、手軽に画像のアップロードが可能でした。