やること
####ユーザーのプロフィール画像の表示とアップロードをできるようにします。
環境
- mac OS Catalina 10.15.6
- Laravel 7.22.4
方法
###1. シンボリックリンク作成
php artisan storage:link
-
シンボリックリンクとは?
簡単に言うと、ショートカットのような機能です。
例えばLaravelでは「一般のユーザーがwebからhtp://xxxxxx/storageに画像を送ると、Laravel内では/storage/app/publicに保存する」という動きをしますが、この紐付けをしているのがシンボリックリンクです。
###2. config/filesystems.phpで1で作成されたシンボリックリンクを確認(必要に応じて追加)
/*
|--------------------------------------------------------------------------
| Symbolic Links
|--------------------------------------------------------------------------
|
| Here you may configure the symbolic links that will be created when the
| `storage:link` Artisan command is executed. The array keys should be
| the locations of the links and the values should be their targets.
|
*/
'links' => [
public_path('storage') => storage_path('app/public'),
],
これでwebから見た時の/storage
とLaravel上のstorage/app/public
がリンクするようになります。
さらに今回は画像を扱う事をわかりやすくするため、公式ドキュメントと同じく、images
フォルダを作成して保存するように設定を追加します。
'links' => [
public_path('storage') => storage_path('app/public'),
public_path('images') => storage_path('app/images'), //追加
],
これでweb上の/images
とLaravel上のstorage/app/images
がリンクします。
※公式ドキュメントでは
Webからのアクセスを許すには、public/storageからstorage/app/publicへシンボリックリンクを張る必要があります。
とありますが、リンクにあるweb上の**public
は不要です。/storage
でアクセスできます。**
このせいでうまくリンクされずに苦労しました。
一行追加したので、反映させるために再度コマンドを打ちます。
php artisan storage:link
###3. 動作確認
試しにstorage/app/images
に画像ファイルを置いてhttp://localhost/images/ファイル名
でアクセスします。
ここまでで表示はできるようになりました。
次はアップロード方法です。
###4. アップロード方法
※enctype='multipart/form-data'
は忘れずにformタグに入れてください。
<form action="/profile/{{$user->name}}" method="POST" enctype='multipart/form-data'>
@csrf @method('PUT')
<input type="file" accept="image/*" name="image">
</form>
上のようにして画像送信をしたら、次はコントローラーでの操作です。
public function update(Request $request, $userName)
{
$user = User::where('name', $userName)->first();
//↓で保存しています。
$filePath = $request->file('image')->store('images');
$user->image = basename($filePath);
$user->save();
return redirect('/profile/' . $userName);
}
順に説明します。
$request->file('image')
では受け取ったimageをfile()
でファイルとして読み込ませます。
store(保存先)
とすることでファイルが保存されます。ファイル名は自動的にIDが割り振られます。変数としてファイルパスが返されるので$filePath
に代入します。
このままだと$filePath
に/public
などの余計な部分が入っているので、basename()
で最後のファイル名の部分のみを取り出して保存させます。
以上でファイルのアップロードも完了です。お疲れさまでした。
####参考
「パブリックディスク」、「ファイルアップロード」を参照