LoginSignup
0
1

More than 1 year has passed since last update.

【Laravel】画像保存処理実行時のエラー対処

Posted at

Laravelで画像保存処理を実行中、遭遇したエラーと対処法をまとめました。

開発環境

  • PHP7.4
  • Laravel6
  • Bootstrap4.4
  • Docker20.10.8

前提

  • 画像保存処理は実装済み
  • テーブル作成・マイグレーション実行済み
  • バリデーション実装済み
  • フォーム作成済み
  • プレビュー表示処理実装済み(JavaScript)
  • Intervention Image インストール済み
  • public artisan storage:link 実行済み

❗注意

コマンドをコピペして実行する際、コマンドの最後に余分なスペースが入らないよう注意しましょう。 コマンドが強制実行される場合があります。実行の際は慎重に。

目次

  1. 画像が正常に保存されない。
  2. GD Library extension not available with this PHP installation.解決

1. 画像が正常に保存されない。

  • フォームをクリックして拡張子.JPEGの画像ファイルを選択。
  • プレビューも正常に表示
    スクリーンショット 2021-11-26 1.07.36.png

  • 更新ボタンクリック後、プロフィール画面に遷移するはずが、バリデーションに引っかかり保存できない。

スクリーンショット 2021-11-26 17.08.35.png

バリデーションは以下の通りです。(画像アップロード処理の部分のみ抜粋)

src/app/Request/UserRequest.php
    public function rules()
    {
        return [
            'avatar' => ['file', 'image'],
        ];
    }

    public function attributes()
    {
        return [
            'avatar' => 'プロフィール画像',
        ];
    }

Viewは以下のとおりです。(画像フォームのみ抜粋)

src/resources/view/users/edit.blade.php
<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"については以下の方の記事をご参考いただくと、理解が深まります。

以下のように修正します。

src/resources/view/users/edit.blade.php
<!-- 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の画像ファイルを選択。
* プレビューも正常に表示
* 更新ボタンクリック後、プロフィール画面に遷移し画像も正常に表示されました。

スクリーンショット 2021-11-26 1.00.57.png

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1