###Laravelで画像保存処理を実行中、遭遇したエラーと対処法をまとめました。
##開発環境
- PHP7.4
- Laravel6
- Bootstrap4.4
- Docker20.10.8
##前提
- 画像保存処理は実装済み
- テーブル作成・マイグレーション実行済み
- バリデーション実装済み
- フォーム作成済み
- プレビュー表示処理実装済み(JavaScript)
-
Intervention Image
インストール済み -
public artisan storage:link
実行済み
##❗注意
:::note warn
コマンドをコピペして実行する際、コマンドの最後に余分なスペースが入らないよう注意しましょう。
コマンドが強制実行される場合があります。実行の際は慎重に。
:::
##目次
- 画像が正常に保存されない。
- GD Library extension not available with this PHP installation.解決
##1. 画像が正常に保存されない。
バリデーションは以下の通りです。(画像アップロード処理の部分のみ抜粋)
public function rules()
{
return [
'avatar' => ['file', 'image'],
];
}
public function attributes()
{
return [
'avatar' => 'プロフィール画像',
];
}
Viewは以下のとおりです。(画像フォームのみ抜粋)
<form method="POST" class="p-3 mb-1" action="{{ route('users.update', ["name" => Auth::user()->name] )}}" >
@method('PUT')
@csrf
-----省略-----
<div class="avatar-form image-picker text-center">
<input type="file" name="avatar" id="avatar" class="d-none @error('avatar') is-invalid @enderror" accept="images/png,image/jpeg" />
<label for="avatar" class="d-inline-block">
@if (!empty($user->avatar))
<img src="/storage/avatars/{{$user->avatar}}" class="rounded-circle" style="object-fit: cover; width: 125px; height: 125px;">
@else
<img src="/images/default.svg" class="rounded-circle" style="object-fit: cover; width: 125px; height: 125px;">
@endif
</label>
<div class="small">プロフィール画像をアップロードできます。</div>
@error('avatar')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
色々調べてみた結果、formタグに以下一文が抜けていたせいで保存出来なかった事が判明
enctype="multipart/form-data"
enctype="multipart/form-data"
については以下の方の記事をご参考いただくと、理解が深まります。
以下のように修正します。
<!-- enctype="multipart/form-data"追加 -->
<form method="POST" class="p-3 mb-1" action="{{ route('users.update', ["name" => Auth::user()->name] )}}" enctype="multipart/form-data">
- 再度フォームをクリックして拡張子
.JPEG
の画像ファイルを選択。 - プレビューも正常に表示
- 更新ボタンクリック後、プロフィール画面に遷移するはずが、今度は以下のエラーに遭遇。
GD Library extension not available with this PHP installation.
##2. GD Library extension not available with this PHP installation.解決
調べてみたところ、インストール済みのIntervention Image
を使用するためには、GD Library
がインストールされていなければならないことが判明
GD Library
のインストール手順は、Dockerfile
にコードを追加して行う方法と、
ターミナルコマンドで実行する方法があるが、私はターミナルコマンドでインストールしたので、その方法を解説します。
appコンテナに入って実行してください
以下コマンドでappコンテナに入る。(環境によってはコマンドが異なります)
$ docker compose exec app bash
以下のコマンドを上から順に実行(PHP7.4の場合)
# apt-get update
# apt-get install -y zlib1g-dev libpng-dev libjpeg62-turbo-dev
# docker-php-ext-configure gd --with-jpeg
# docker-php-ext-install -j$(nproc) gd
インストールできたらコンテナの再起動をしてください。
以下のコマンドで実行
$ docker restart コンテナ名
コンテナ再起動後、再び画像を保存してみる。
- 再度フォームをクリックして拡張子
.JPEG
の画像ファイルを選択。 - プレビューも正常に表示
- 更新ボタンクリック後、プロフィール画面に遷移し画像も正常に表示されました。
##参考