質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.35%

  • PHP

    15175questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Laravel 5

    930questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

  • Framework

    86questions

    Frameworkは、アプリケーションソフトを開発する際に、一般的な機能をより簡単に、より早く完了させる事を目的とした、ソフトウェアやライブラリのセットを指します。開発にフレームワークを使用する事で、追加で必要となる機能だけを開発するだけで済む為、開発効率の向上が見込めます。

Laravel5.4 ファイルアップロード時のエラー処理の対処がわからない

解決済

回答 1

投稿 2017/12/07 15:43 ・編集 2017/12/08 12:49

  • 評価
  • クリップ 0
  • VIEW 91

hidepon

score 131

Laravel5.4 でファイルアップロードを試みていますが、エラー処理部分で躓きドキュメントを見ても対処が分かりません。

routes/web.php

Route::get("/about","PagesController@getIndex");
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Route::get('/', 'UploadController@index');
Route::post('/store', 'UploadController@store');


app/Http/Controllers/UploadController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UploadController extends Controller
{

    public function index(Request $request)
    {
        return view('uploads');
    }

    public function store(Request $request)
    {
        $this->validate($request, [
             'datafile' => 'image|max:3000',
        ]);
        if ($request->file('datafile')->isValid())
        {
            //アップロード成功時の処理
            return view('upload_success');
        }else{
            //失敗時の処理
            return view('upload_error');
        }
    }
}

resource/view/uploads.blade.php

@if (isset($message))
        <div class="alert">{{$message}}</div>
@endif

       <form action="/store" method="post" enctype="multipart/form-data">
         <input type="file" name="datafile">
         <input type="submit" value="アップロード" />
         {{ csrf_field() }}
       </form>
@section('content')
    <div class="container">
        @if (count($errors) > 0)
            <div class="alert alert-danger">
                <ul>
                    @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        @endif
    </div>
@endsection


エラー発生
resource/view/upload_error

@section('content')
    <div class="container">
        @if (count($errors) > 0)
            <div class="alert alert-danger">
                <ul>
                    @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        @endif
       <form action="/store" method="post" enctype="multipart/form-data">
         <input type="file" name="datafile">
         <input type="submit" value="アップロード" />
         {{ csrf_field() }}
       </form>
    </div>
@endsection


成功時
resource/view/upload_success

@section('content')
    <div class="container">
      <p>アップロードが成功しました。
    </div>
@endsection

エラー処理時の方法が分からず困っています。
宜しくお願いいたします。
(追記)
できれば、ほかのフレームワークでやっていたようなことができればうれしいんですが、、、、
/store
に遷移した段階でエラーがあればエラーメッセージとファイル選択のフォームを再度表示。
ファイルが送信されていれば、保存ということをしたいです。

公式ドキュメントではこのような内容が読み取れず、できるのか判断出来ない状況です。
ちなみにほかのフレームワークでは
if (エラーあり){
view(エラーのテンプレート);
}else{
view(成功のテンプレート);
}
としていました。
このような仕組みってできるんでしょうか?
宜しくお願いいたします

(追記2)
ご回答内容を反映しました。

(現在の状況)
routes/web.php

Route::get('/', 'UploadController@index');
Route::post('/add', 'UploadController@add');

app/Http/Controllers/UploadController.php

?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UploadController extends Controller
{
    //view
    public function index()
    {
        return view('index');
    }

    //postした後の処理
    public function add(Request $request)
    {
         $this->validate($request, [
            'file' => 'image|max:3000',
         ]);

        if ($request->file('file')->isValid())
        {
            //アップロード成功時の処理
            return view('upload_success');
        }
    }
}


resource/view/index.blade.php

<!DOCTYPE html>
<html>
<head>
<title>sample</title>
<meta charset="utf-8">
</head>
<body>

<!-- エラーメッセージ表示部分-->
@if ($errors->any())
     @foreach ($errors->all() as $error)
        <p>{{ $error }}</p>
    @endforeach
@endif
<!-- エラーメッセージ表示部分-->

<form action="/add" method="post" enctype="multipart/form-data">
     {{ csrf_field() }}
    <input type="file" name="file">
    <input type="submit">
</form>
</body>
</html>


resource/view/i.blade.php

<!DOCTYPE html>
<html>
<head>
<title>sample</title>
<meta charset="utf-8">
</head>
<body>
<p>アップロード成功しました</p>
</body>
</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hidepon

    2017/12/07 17:05

    そうですね。ほとんど投稿の内容から大きく操作していないですが。。

    キャンセル

  • mts10806

    2017/12/07 17:18 編集

    そもそもですが、uploads.blade.phpにfile選択(input type=file)自体ないような。。。

    キャンセル

  • hidepon

    2017/12/07 17:27

    viewに記述ミスがありました。あれやこれやを繰り返しているなかでのミスです。すみません。

    キャンセル

回答 1

checkベストアンサー

+1

このコードで5.4で動くことを確認しました。

route
Route::get('/', 'UploadController@index');
Route::post('/add', 'UploadController@add')->name('add');
viewファイル

<!DOCTYPE html>
<html>
<head>
<title>sample</title>
<meta charset="utf-8">
</head>
<body>

<!-- エラーメッセージ表示部分-->
@if ($errors->any())
     @foreach ($errors->all() as $error)
        <p>{{ $error }}</p>
    @endforeach
@endif
<!-- エラーメッセージ表示部分-->

<form action="{{route('add')}}" method="post" enctype="multipart/form-data">
     {{ csrf_field() }}
    <input type="file" name="file">
    <input type="submit">
</form>
</body>
</html>
コントローラー

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{
    //view
    public function index()
    {
        return view('index');
    }

    //postした後の処理
    public function add(Request $request)
    {
         $this->validate($request, [
            'file' => 'required|image|max:3000',
         ]);

        if ($request->file('file')->isValid())
        {
            //アップロード成功時の処理
        }
    }
}

エラーが出た場合は元のviewファイルにリダイレクトし、エラーメッセージを表示してくれます。エラーメッセージを変えたい場合は、resources/lang/en/validation.phpを直接いじるか、追加するなりで対応できます。詳しくはここで解説してます。
https://qiita.com/komatzz/items/422bcba9847ca3a79fe9

一度これに合わせてコードを書きなおしてみてください。

投稿 2017/12/07 16:30

編集 2017/12/08 13:47

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/07 16:49

    ご返答ありがとうございます。やってみましたが、うまく動作しませんね・・・。いろいろと手を加えていこうと思います。5.3と5.4でもこんなに違うんですね・・・・

    キャンセル

  • 2017/12/07 16:52

    上手く動作しないとは、具体的になにかエラーが出ているという事ですか?

    キャンセル

  • 2017/12/07 16:54

    申し訳ありません。「Call to a member function isValid() on null」というエラーが出ているです。これは5.4で変わったんですかね???宜しくお願いいたします

    キャンセル

  • 2017/12/07 17:00

    一度コントローラー側のソースを見てみたいですね。何かわかるかもしれませんし。

    キャンセル

  • 2017/12/07 17:06

    ご返答ありがとうございます。質問部分に追記更新します。よろしくお願いいたします。

    キャンセル

  • 2017/12/07 17:13

    ご回答内容からの編集事項を反映しました。エラー時にエラー用のview (error.blade.php)を作成してエラー内容を埋め込みたいです。
    宜しくお願いいたします。

    キャンセル

  • 2017/12/07 17:17

    ファイルアップロードなのに、type="file"のinput要素が1つもないのは何故ですか?ちなみに
    $request->file('file')->isValid()
    の('file')部分はそのinput要素の名前が入ります。

    キャンセル

  • 2017/12/07 17:28

    申し訳ありません。いろいろと試行錯誤しているなかでの転載ミスです。気づきませんでした。ご指摘有難うございます。

    キャンセル

  • 2017/12/07 17:31

    nameがdatafileになっているので、それに合わせる必要がありますね。回答の方修正しておくので、それで試してもらえませんか?

    キャンセル

  • 2017/12/07 17:34

    ご指摘の直後にこちらでも早速修正をしてみました。有難うございます

    キャンセル

  • 2017/12/07 17:38

    これでもまだエラーが出てますか?

    キャンセル

  • 2017/12/07 17:45

    なんか挙動がおかしくて・・・・質問欄に現状を記述しますね。本当にすみません。有難うございます。

    キャンセル

  • 2017/12/07 17:56

    datafileじゃなくて、adtafileになってますね。もしやここが原因では?

    キャンセル

  • 2017/12/07 18:02

    こちらも質問欄への記述ミスです・・・。焦るとだめですね・・・すみません。

    キャンセル

  • 2017/12/07 18:06

    エラー処理時に「Call to a member function isValid() on null」
    成功時は画面が真っ白になります。

    キャンセル

  • 2017/12/07 18:16

    気づくの遅れました・・・。バリデーションのfile部分をdatafileに直してみてくれませんか?

    キャンセル

  • 2017/12/07 18:23

    有難うございます。修正してみましたが、うまく動作しないようです。
    「Call to a member function isValid() on null」というエラー表示になります

    キャンセル

  • 2017/12/07 18:35

    意外と難しいですね・・・5.3 と5.4の違いなんでしょうか???

    キャンセル

  • 2017/12/07 18:42

    バージョン違いではないとは思うんですけどね。最新版で動かしたら動いたので・・。inputのname部分とバリデーションの部分とif分のところで完全に一致してるんですよね?

    キャンセル

  • 2017/12/07 19:04

    質問欄に最新の状態で更新しました。name部分とか一致しているはずなんですが・・・

    キャンセル

  • 2017/12/07 19:27

    5.4で検証してないので、しばらく調査してみます。何かわかったらコメントします。お役に立てずすみません・・・

    キャンセル

  • 2017/12/08 00:11

    いえいえ、有難うございます。本当によくわからなくて・・・本当にありがとうございます。自分も試行錯誤でしています

    キャンセル

  • 2017/12/08 10:03

    回答更新したので、試してみてください

    キャンセル

  • 2017/12/08 12:42

    有難うございます。。ほぼほぼコピペでやってみましたが、うまくいきません。routeとかファイル名の変更をした内容を質問部分の最下部に追記します

    キャンセル

  • 2017/12/08 12:59

    routeの設定を変更して、viewの設定を変更したのですが、成功時のファイルに記述した内容が表示されないです。また失敗時の処理も「Call to a member function isValid() on null」とlaravelの処理になってしまいます

    キャンセル

  • 2017/12/08 13:20

    ルート部分とform action部分を変えたので、それで試してもらえますか?あと成功時のファイル名がi.blade.phpになってますが、書き間違いでしょうか。

    キャンセル

  • 2017/12/08 13:26

    有難うございます。viewの名称の部分は書き間違えです。upload_success.blade.phpです。すみません。チョンボが多くて・・・やってみます。

    キャンセル

  • 2017/12/08 13:30

    まさかとは思うんですが、確認するときにちゃんとファイルを選択して送信してますよね?何も選択しないで送信したら「Call to a member function isValid() on null」のエラーが出るのは今確認できました。もしこの辺りもバリデーションするならコードを足す必要があります。

    キャンセル

  • 2017/12/08 13:33

    何も選択していない場合は「Call to a member function isValid() on null」と出るんです。これは当然の結果だったということですね・・・。説明不足ですみません。最終的には「未選択」と「容量オーバー」「拡張子ダメです」の3点はチェックしたいと思っています。成功時に「upload_success.php」が表示されていないようです。この理由がわからないままです

    キャンセル

  • 2017/12/08 13:38

    こちらでも同じ状況にしましたが、正しくviewファイルが表示されました。upload_success.phpではなく、upload_success.blade.phpとなっていますか?

    キャンセル

  • 2017/12/08 13:40

    そのとおりでuoload_success.blade.phpになっています。もう一度確認してみます。本当にすみません。

    キャンセル

  • 2017/12/08 13:44

    upload_success.blade.phpとなっているなら
    return view('upload_success');
    とすれば必ず表示されるはずです。

    キャンセル

  • 2017/12/08 13:45

    うまくいきました!!!ありがとうございます。変な文字@section("cotents")という感じの文字が入っていました。これが原因だったようです。すみません。「ファイル選択がない」「容量オーバー」「拡張子ダメ」のエラー処理もやってみようと思います

    キャンセル

  • 2017/12/08 13:48

    ファイル項目を必須にする場合はバリテーションにちょっと追加するだけですね。コード変えてみたんで試してみてください。

    キャンセル

  • 2017/12/08 13:53

    えっ!?こんな簡単な感じでバリデーションできるんですか!?素晴らしいです。本当に有難うございました。これからも勉強を進めていきます。心折れそうでした。。。orz

    キャンセル

  • 2017/12/08 13:56

    いやー解決できてよかった(笑) バリデーションの項目は公式ドキュメントに載ってるので読んでみるといいですよ。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.35%

関連した質問

同じタグがついた質問を見る

  • PHP

    15175questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Laravel 5

    930questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

  • Framework

    86questions

    Frameworkは、アプリケーションソフトを開発する際に、一般的な機能をより簡単に、より早く完了させる事を目的とした、ソフトウェアやライブラリのセットを指します。開発にフレームワークを使用する事で、追加で必要となる機能だけを開発するだけで済む為、開発効率の向上が見込めます。