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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

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

Laravel 5

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

Q&A

解決済

2回答

25295閲覧

Laravel postで送信しているのにgetエラー

Chandler_Bing

総合スコア673

PHP

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

Laravel 5

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

0グッド

1クリップ

投稿2019/06/13 08:28

編集2019/06/14 07:44

お疲れ様です。先日のエラーですがミニプログラムを作成したので、添付します。

オリジナルのバリデートを作成しているクラス

php

1<?php 2 3namespace App\Providers; 4 5use Illuminate\Support\ServiceProvider; 6use Illuminate\Support\Facades\Validator; 7 8class Test_ValidationServiceProvider extends ServiceProvider 9{ 10 /** 11 * Register services. 12 * 13 * @return void 14 */ 15 public function register() 16 { 17 // 18 } 19 20 /** 21 * Bootstrap services. 22 * 23 * @return void 24 */ 25 public function boot() 26 { 27 28 //特殊文字は許さない 29 /*以下の条件に一致しない(特殊文字が含まれている)ときにエラー処理を行う*/ 30 Validator::extend('invalid', function ($attribute, $value, $parameters, $validator) { 31 $pattern = '-._~%:/?#[]@!$&\'()*+,;='; 32 $pattern = preg_quote($pattern, '/'); 33 $pattern = "/[^" . $pattern . "]/"; 34 return preg_match($pattern, $value); 35 }); 36 37 //IDとパスワードはパスワードは英数字を含んだ16文字以下 38 Validator::extend('passid', function ($attribute, $value, $parameters, $validator) { 39 return preg_match("/\A(?=.*?[a-z])(?=.*?\d)[a-z\d]{5,16}+\z/i", $value); 40 }); 41 } 42}

ルートです

php

1//テンプレであるコメントアウトは提示していません。 2Route::get('/', 'TestController@basic1'); 3Route::post('/basic1', 'TestController@basic1Check'); 4Route::post('/basic2', 'TestController@basic2');

オリジナルのバリデートをルールに追加しています

php

1<?php 2namespace App\Http\Requests; 3use Illuminate\Foundation\Http\FormRequest; 4 5class TestRequest extends FormRequest 6{ 7 /** 8 * Determine if the user is authorized to make this request. 9 * 10 * @return bool 11 */ 12 public function authorize() 13 { 14 return true; 15 } 16 17 /** 18 * Get the validation rules that apply to the request. 19 * 20 * @return array 21 */ 22 public function rules() 23 { 24 return [ 25 'name' => 'required|invalid|', 26 'id' => 'passid', 27 'pass' => 'passid|different:id', 28 ]; 29 } 30 31 public function messages() 32 { 33 return [ 34 //名前のバリデーション 35 'name.required' => '名前の入力は必須です', 36 'name.invalid' => '名前に使用できない文字が含まれています', 37 //idのバリデーション 38 'id.passid' => 'ログインIDは英数字を含んだ16文字以下で入力してください', 39 //passのバリデーション 40 'pass.passid' => 'パスワードは英数字を含んだ16文字以下で入力してください', 41 'pass.different' => 'IDと同じパスワードは設定できません', 42 ]; 43 } 44}

コントローラーです

php

1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\Request; 6use App\Http\Requests\TestRequest; 7 8class TestController extends Controller 9{ 10 //一番初めに呼ばれます 11 public function basic1() 12 { 13 $hash = array( 14 'name' => null, 15 'id' => null, 16 'pass' => null, 17 ); 18 return view('tests.test_basic1')->with($hash); 19 } 20  //test_basic1から送信された値がバリデートを通過したあとの処理です 21 public function basic1Check(TestRequest $request) 22 { 23 $name = $request->name; 24 $id = $request->id; 25 $pass = $request->pass; 26 //値を配列に格納し、分解します 27 $basic1 = ['name' => $name, 'id' => $id, 'pass' => $pass]; 28 //この値がtest_basic2のbuttonタグのvalueに入ります 29 $basic1Str = implode(',', $basic1); 30 return view('tests.test_basic2', ['basic1Str' => $basic1Str]); 31 } 32 33 public function basic2(Request $request) 34 { 35//このifでbackボタンが押されたかどうか判断していま 36 if (isset($request->basic1Str)) { 37 $basic1 = explode(',', $request->basic1Str); 38 $name = $basic1[0]; 39 $id = $basic1[1]; 40 $pass = $basic1[2]; 41 42 $hash = array( 43 'name' => $name, 44 'id' => $id, 45 'pass' => $pass, 46 ); 47 return view('tests.test_basic1')->with($hash); 48 } 49 return view('tests.test_basic2'); 50 } 51}

以下bladeです

blade

1{{--一部抜粋です(test_basic1.php)--}} 2 <form method="post" action="/basic1"> 3 {{ csrf_field() }} 4 <p>ナマエ</p> 5 <input type="text" name="name" value="{{ old('name', $name) }}"> 6 @if ($errors->has('name')) 7 <span class="errormsg">{{ $errors->first('name') }}</span> 8 @endif 9 10 11 <p>ログインID</p> 12 <input type="text" name="id" value="{{ old('id', $id) }}"> 13 @if ($errors->has('id')) 14 <span class="errormsg">{{ $errors->first('id') }}</span> 15 @endif 16 17 18 <p>パスワード</p> 19 <input type="text" name="pass" value="{{ old('pass', $pass) }}"> 20 @if ($errors->has('pass')) 21 <span class="errormsg">{{ $errors->first('pass') }}</span> 22 @endif 23 24 <button type="submit" class="btn btn-primary mb-5">Next</button> 25 </form>

blade

1{{--一部抜粋です(test_basic2.php)--}} 2 <form method="post" action="/basic2"> 3 {{ csrf_field() }} 4 5 <select id="inputReason" class="custom-select"> 6 <option selected>Open this select menu</option> 7 <option value="1">One</option> 8 <option value="2">Two</option> 9 <option value="3">Three</option> 10 </select> 11 <button type="submit">Next</button> 12 <button type="submit" name="basic1Str" value="{{ $basic1Str }}">back</button> 13 </form>

問題
①一番初めにurlに'/'のurlを打つ

②test_basic1.blade.php表示


test_basic1.balde.phpでバリデートを通過する値を入力(通過しない値でもきちんと画面に設定したエラーメッセージがでる。)

④通過するとtest_basic2.blade.phpを表示(backボタンのvalueにはtest_basic1で入力した値がきちんと入っていることは確認済みです)

⑤backボタンを押す

⑥test_basic1.blade.phpが表示され、先ほど入力した値がすでに入力済み(期待値)

⑦-1
バリデート通過する値を入力すると問題なくtest_basic2.blade.phpが表示される
⑦-2
バリデート通過しない値を入力すると以下のエラーが表示される

error

1The GET method is not supported for this route. Supported methods: POST.

一番初めにtest_basic1.blade.phpでバリデートエラーを出してもtest_basic2.blade.phpからtest_basic1.blade.phpに戻ってきてバリデートエラーを出しても動きは同じだと思うのですが、何が問題でしょうか。

またバリデートクラスの作成は以下のサイトの方法と全く同じです。
Laravelのカスタムバリデーション

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/06/13 08:36

BasicRequestという独自の指定の情報なしに回答しろと言われても。 長くて載せられないのならせめて問題が再現する最小構成のコードを提示してください。 https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5 #2. エラーが再現する小さなプログラムを作る
m.ts10806

2019/06/13 08:39

>2ページ目から1ページ目に戻り、 どうやって戻っているのでしょうか。再現確認で提示すべきコードが抜けています。
fumifumi_60

2019/06/13 08:40

私の理解力の問題かもしれませんが 『エラー値を入力』というのが分からないです、 コードのどの辺の挙動なのか、教えていただけますか?
Chandler_Bing

2019/06/13 08:45

ミニプログラムを作成しコード再記載します。 諸事情により、かなり後になるか明日になるかのどちらがですが、その際はまたよろしくお願いします。
zushi0905

2019/06/13 08:52

戻るの意味がよく分かってないですけど、下のbladeでNextもbackも両方/basic2にpostしているのはなんででしょう?
m.ts10806

2019/06/13 08:53

たぶん埋もれるので、なかったことにして放置します。 これまでの経緯から本当にそのまま再現確認できるコードが提示されるか怪しいので。 (できるなら最初から提示している。これだけの質問書く時間が勿体ない)
guest

回答2

0

ベストアンサー

一番初めにtest_basic1.blade.phpでバリデートエラーを出しても

test_basic2.blade.phpからtest_basic1.blade.phpに戻ってきてバリデートエラーを出しても
動きは同じ

「動きは同じ」様に見えますが、実際には同じではありません。

bladeファイルを中心にお話されていますが、論点が違います。。。

バリデーションエラー時の処理は、「ひとつ前のURLにGETでリダイレクト」です。
画面表示に使っているbladeファイルは、バリデーションエラーの戻り先には影響しません。

単純にひとつ前の「画面」に戻る・・・と考えると、「同じbladeファイルを使っている」ので同じ画面のような気がしてしまうのかもしれませんが、
【一番初めにtest_basic1.blade.php】の画面と、
【test_basic2.blade.phpからtest_basic1.blade.phpに戻って】の画面は、URLが違うので別の画面です。

一番初めにtest_basic1.blade.phpでバリデートエラー

スタート時点の入力画面のURLは「/」なので、エラー時の戻り先は「/」です。

実際の画面遷移は、/から、/basic1にpostしたけど、バリデーションエラーだから/にGETで戻るよ
となり、最後に戻ってきた/は、ルートがGET設定なので、ここでは問題は起きません。

一方、

test_basic2.blade.phpからtest_basic1.blade.phpに戻ってきてバリデートエラー

こちらの場合、入力画面のURLは「/basic2」なので、エラ-時の戻り先も「/basic2」です。

実際の画面遷移は、/basic2から、/basic1にpostしたけど、バリデーションエラーだから/basic2にGETで戻るよ
となるわけですが、こちらは最後に戻ってきた/basic2のルートはPOSTで設定されていますので、バリデーションエラー時にGETでリダイレクトされてきたアクセスはエラーになります。

The GET method is not supported for this route. Supported methods: POST.

が発生しているのはココなので、POST送信したかどうかではなく、バリデーションエラー発生時の戻り先URLがGETアクセスできないことが原因です。


解決には、「戻る機能」の仕組みを変更するとか、バリデーションエラー時のリダイレクト先を/に共通化するとか・・・何かしらの工夫が必要かなと思います。

投稿2019/06/18 07:26

mix-peach

総合スコア1910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chandler_Bing

2019/07/01 06:23

全く知りませんでした。解決しました。ありがとうございます。
guest

0

2ページ目のこの部分がbackもポストになっていますね。

<div class="form-group mb-5"> <button type="submit" class="btn btn-primary mr-5">Next</button> <button type="submit" class="btn btn-secondary" id="" name="basic1Str" value="{{ $basic1Str }}">back</button> </div>

type="submit"は指定されたポストのアクションを起こすということなので。
type="submit"は本来ポストしたい項目のみ適用してください。

では、GETでどうするのかというと

<button onclick="location.href='{{ url()->previous() }}'"> back </button>

これでGETとして送信できるはずです。

しかし、他にも問題点がありそうですね。
仕様がよく理解できていないのでこれで意図した挙動になるかは不透明です。

P.S.
推奨はいたしませんが、GETでもPOSTでも通す方法はあります

Route::match(['get', 'post'], 'foo','HomeController@index');

参考:https://qiita.com/fagai/items/a1bf55b6249aee03a624

投稿2019/06/13 09:06

編集2019/06/13 09:16
fumifumi_60

総合スコア36

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chandler_Bing

2019/06/14 07:37

試してみます。同じエラーを出すミニプログラムを作成したのでそちらも目を通していただけたら嬉しいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問