Livewire でS3にファイルアップロードするには?

ショコラ
ショコラ

Livewire でS3にファイルアップロードするには?

https://laravel-livewire.com/docs/2.x/file-uploads を参考にファイルアップロードを作ってみます。

もっさん先輩
もっさん先輩

手順

Laravel と Livewire をインストールして、s3 にファイルアップロードするサンプルプログラムを作成する手順。

  1. プロジェクト名(s3upload)を決めて以下のコマンドを実行します。
curl -s https://laravel.build/s3upload | bash

インストール時にプロジェクト名のディレクトリが作成されます。

  1. インストールの最後に sudo でパスワードの入力を求められます。

↓下のメッセージが表示されてインストールは終わります。

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

Get started with: cd s3upload && ./vendor/bin/sail up
  1. sail のエイリアスを定義します。
echo "alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'" >> ~/.bashrc
source ~/.bashrc

Laravel のインストールはここまで。

  1. 「sail up」でコンテナを起動します。
cd s3upload && sail up -d
  1. ララベルのトップディレクトリで、Livewireパッケージ をインストールします。
sail composer require livewire/livewire
  1. league/flysystem-aws-s3-v3 パッケージ をインストールします。
sail composer require league/flysystem-aws-s3-v3
  1. .envファイル を修正します。
AWS_ACCESS_KEY_ID={設定する}
AWS_SECRET_ACCESS_KEY={設定する}
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET={設定する}
AWS_USE_PATH_STYLE_ENDPOINT=false
AWS_URL=https://{バケット名を設定する}.s3.ap-northeast-1.amazonaws.com/
  1. 次のコマンドを実行して、uploadコンポーネント を生成します。
sail artisan make:livewire upload
$ sail artisan make:livewire upload
 COMPONENT CREATED  ?

CLASS: app/Http/Livewire/Upload.php
VIEW:  resources/views/livewire/upload.blade.php

次の 2つ のファイルが生成されます。

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Upload extends Component
{
    public function render()
    {
        return view('livewire.upload');
    }
}
<div>
    {{-- Be like water. --}}
</div>

※因みに、renderメソッド を定義しなくても livewire.upload は呼び出されます。

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Upload extends Component
{
}
  1. 生成された uploadコンポーネント のクラスとビューを次のように置き換えます。
<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Livewire\WithFileUploads;

class Upload extends Component
{
    use WithFileUploads;

    public $photo;
    public $photo_url;

    public function updatedPhoto()
    {
        $this->photo_url = $this->photo->temporaryUrl();
    }

    public function save()
    {
        $this->validate([
            'photo' => 'image|max:1024', // 1MB Max
        ]);

        // 拡張子取得
        $ext = $this->photo->getClientOriginalExtension();

      //$this->path = $this->photo->store('public');
        $this->photo_url = env('AWS_URL').$this->photo->storeAs('img','photo1.'.$ext,'s3');
    }
}
<form wire:submit.prevent="save">
  <div style="max-width:500px">
    <div class="droparea" style="position:relative; aspect-ratio:100/66; @isset ($photo_url) background-image:url({{ $photo_url }}); background-size:cover; @endif">
      <div class="shadow" style="position:absolute;width:100%;height:100%; background-color:#000;opacity:0.3;"></div>
      <div class="foreground" style="position:absolute;inset:10px; display:flex;justify-content:center;align-items:center; color:#FFF;font-weight:bold; border: dashed 3px #FFF;">
        画像ファイルをここにドロップしてください。
      </div>
      <input type="file" wire:model="photo" style="opacity:0;width:100%;height:100%;">
    </div>
    @error('photo') <span class="error">{{ $message }}</span> @enderror
    <button type="submit">Save Photo</button>
  </div>
</form>
  1. resources/views/layouts/app.blade.phpファイル を作る為に、layoutディレクトリ を作成します。

「フルページコンポーネントは resources/views/layouts/app.blade.php の {{ $slot }} にレンダーされる」と見かけましたが、ここまでの手順で app.blade.phpファイル はできていませんでしたので作成します。

mkdir resources/views/layouts/
  1. resources/views/layouts/app.blade.phpファイル を作成します。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <livewire:styles />
  </head>
  <body>
    {{ $slot }}
    <livewire:scripts />
  </body>
</html>
  1. routes/web.php に Livewireコンポーネント のルートを追加します
Route::get('/',App\Http\Livewire\Upload::class);
  1. ブラウザで確認します。

Save Photo で S3 にファイルを保存します。

以上

Scroll to Top