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

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

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

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

Blade

Bladeとは、 PHPフレームワークのLaravelで使用することができるテンプレートエンジンです。テンプレートの継承とエスケープ機能を提供します。

Laravel 5

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

Q&A

解決済

1回答

2580閲覧

フォームリクエストを利用してのバリデーション実装と日本語化について

djkddsjk

総合スコア14

PHP

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

Blade

Bladeとは、 PHPフレームワークのLaravelで使用することができるテンプレートエンジンです。テンプレートの継承とエスケープ機能を提供します。

Laravel 5

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

1グッド

1クリップ

投稿2017/10/10 09:38

###前提・実現したいこと
現在、Laravel5.4にて、フォームリクエストを利用して、バリデーションの実装をしようとしております。
どのようにしましたら、以前のように、1つの項目名に対して複数のエラーを表示させることができるのでしょうか?

また、中途半端な日本語になってしまっているバリデーションエラーメッセージを、設定した日本語での表示に切り替えることができるのでしょうか?

フォームリクエストを利用する以前に、コントローラにバリデーションを書いていたときには、設定した項目名に対して、複数のエラーが生じた際には、複数のメッセージが表示されていたのですが、フォームリクエストを利用してからは、1つの項目名に対して、1つのエラーのみ表示されるようになってしまいました。

テンプレートには、$errors->first(項目名)ではなく、$errors->get(項目名)を使用し、
もしも、@errors に値が保管されている場合は、$errors からエラーメッセージをまとめて取り出して、@foreach を使い、順に出力していくようにしているつもりです。

どのようにしましたら、以前のように、1つの項目名に対して複数のエラーを表示させることができるのでしょうか?

また、エラーメッセージにつきましても、日本語にしようとしているのですが、それも中途半端になってしまっております。
日本語の設定をしているつもりのバリデーションルールも、日本語が当てがわれて表示されていない状態です。
私のブラウザ環境では、required は設定した日本語に変わっておりますが、文字数のバリデーションルールにつきましては、元の英語のままとなってしまっております。

そちらにつきましても、どのようにしましたら良いのでしょうか?

ご教示いただけますでしょうか? 何卒よろしくお願い申し上げます。

###発生している問題・エラーメッセージ

以下は、ブラウザでのバリデーションエラーメッセージです。

ERORR The age must be between 0 and 150. ← こちらが日本語になりません。 ERORR お名前は必ずご入力してください。 ← こちらは設定した日本語の通りに表示されております。

###該当のソースコード
Laravel5.4

HelloRequest.php

<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class HelloRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { if($this->path() === 'hello'){ return true; } else { return false; } } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|string|between:2, 40', 'mail' => 'required|email', 'age' => 'numeric|between:0, 150', ]; } public function messages() { return [ 'name.required' => 'お名前は必ずご入力してください。', 'name.string' => 'お名前は文字でのご入力をお願いいたします。', 'name.between:2,40' => 'お名前は2文字以上、40文字以内にてお願いいたします。', 'mail.required' => 'メールアドレスは必ずご入力してください。。', 'mail.email' => 'メールアドレスの形式になっておりません。', 'age.numeric' => 'ご年齢は整数でのご入力をお願いいたします。', 'age.between:0,150' => 'ご年齢は 0 〜 150 の間でご入力をお願いいたします。', ]; } }

index.blade.php

@section('content') <p>{{$msg}}</p> @if (count($errors) > 0) <p>入力に問題があります。再入力してください。</p> @endif <table> <form class="" action="/hello" method="POST"> {{ csrf_field() }} @if ($errors->has('name')) <tr><th>ERORR</th><td>@foreach ($errors->get('name') as $error) <td>{{ $error }}</td> @endforeach</td></tr> @endif <tr><th>name:</th><td><input type="text" name="name" value="{{ old('name') }}"></td></tr> @if($errors->has('mail')) <tr><th>ERORR</th><td>@foreach ($errors->get('mail') as $error) <td>{{ $error }}</td> @endforeach</td></tr> @endif <tr><th>mail:</th><td><input type="text" name="mail" value="{{ old('mail') }}"></td></tr> @if($errors->has('age')) <tr><th>ERORR</th><td>@foreach ($errors->get('age') as $error) <td>{{ $error }}</td> @endforeach</td></tr> @endif <tr><th>age:</th><td><input type="text" name="age" value="{{ old('age') }}"></td></tr> <tr><th></th><td><button type="submit" name="" value="send">送 信</button></td></tr> </form> </table> @endsection

###補足情報(言語/FW/ツール等のバージョンなど)
Laravel5.4

m.ts10806👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーメッセージが日本語にならない

https://readouble.com/laravel/5.4/ja/validation.html

「カスタムエラーメッセージ」項を参照してください。

そちらを見ていただくとわかると思うのですが、betweenの場合のエラーメッセージの書き方が誤っています。

public function messages() { return [ 'name.required' => 'お名前は必ずご入力してください。', 'name.string' => 'お名前は文字でのご入力をお願いいたします。', // 'name.between:2,40' => 'お名前は2文字以上、40文字以内にてお願いいたします。', 'name.between' => 'お名前は :min 文字以上、:max 文字以内にてお願いいたします。', 'mail.required' => 'メールアドレスは必ずご入力してください。。', 'mail.email' => 'メールアドレスの形式になっておりません。', 'age.numeric' => 'ご年齢は整数でのご入力をお願いいたします。', // 'age.between:0,150' => 'ご年齢は 0 〜 150 の間でご入力をお願いいたします。', 'age.between' => 'ご年齢は :min 〜 :max の間でご入力をお願いいたします。', ]; }

と変更すれば日本語になるのではないかと思いますが、お試しいただけますか?(動作未検証)

エラーメッセージが1つしか表示されない

ご質問の件に入る前に……。
(直接の原因かどうかはわかりませんが)テーブルタグの構造がおかしいようです。

↓例:年齢のエラーメッセージ

@if($errors->has('age')) <tr><th>ERORR</th><td>@foreach ($errors->get('age') as $error) <td>{{ $error }}</td> @endforeach</td></tr> @endif

こちら、エラーメッセージが2つだったとして

<tr><th>ERORR</th><td><td>{{ $error }}</td><td>{{ $error }}</td></td></tr>

という構造になってしまっています(<td>タグの中にまた<td>が入っている)。

エラーメッセージが増える度にテーブルタグの<td>を増やしていくのは現実的ではないと思いますので、

@if($errors->has('age')) <tr><th>ERORR</th><td>@foreach ($errors->get('age') as $error) {{ $error }}<br/> @endforeach</td></tr> @endif

@if($errors->has('age')) <tr><th>ERORR</th><td>@foreach ($errors->get('age') as $error) <p>{{ $error }}</p> @endforeach</td></tr> @endif

等に変更してください。


まずは、上記を修正していただき「エラーメッセージがきちんと表示できる状態」にしてください。

その上で、肝心な「エラーメッセージが1つしか表示されない」についてですが……。

betweenの挙動が入力値の型によって変わってしまうため(数値の場合は値チェック、文字列の場合は文字数チェック)、「エラーが1つしか出ていない」のか「本当はエラーが2つあるのに、出力だけが1つになっている」のか判別がつきにくいですね。

どちらの問題なのか切り分けるために、テスト的に、name欄に文字種制限(英字のみ可:alpha)をかけてみていただけますか?

public function rules() { return [ // 'name' => 'required|string|between:2, 40', 'name' => 'required|string|alpha|between:2, 40', 'mail' => 'required|email', 'age' => 'numeric|between:0, 150', ]; }

この状態で、41文字以上、かつ、アルファベットだけではない文字列(例: aaaaabbbbbcccccddddd11111222223333344444a )を入力し、結果を確認してみてください。

  • エラーメッセージが2つ表示された(文字数エラー&文字種エラー):

 「複数エラーメッセージを取得する」処理は正しく行えているようです。
既存のバリデーションでエラーメッセージが1つしか出力されないのは、「メッセージが出力されない」ではなく、betweenの仕様(データ型によってチェック内容が変わってしまう)のせいで、エラーチェックが1つずつしか行われていないのではないかと思われます。

  • エラーメッセージが1つしか表示されない:

 エラーメッセージの出力方法に問題があるのかもしれません(処理を拝見する限り、マニュアルどおりのように見受けられるのですが……)。
試しに $errors->all() で全てのエラーメッセージを確認すると、どうなっていますか?
https://readouble.com/laravel/5.4/ja/validation.html

追伸:
「エラー」のtypoが散見されますので、ついでに修正されることをおすすめします(ERORR → ERROR)。

投稿2017/10/11 05:20

nak

総合スコア696

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

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

djkddsjk

2017/10/11 08:55

nak様、本当にありがとうございます。解決できました! ご教示いただきました、alpha での検証及び、html の修正、between の書き方(完全に間違って覚えておりました..大変申し訳ございません.)等、すべて私の方でも検証させていただきました。 エラーメッセージが1つしか表示されないの件につきましても、ご指摘いただきました検証方法にて複数表示を確認できました。ありがとうございます。$errors->all()や、私が元々書いていた$errors->get('name')でも、複数表示を確認できました。追伸いただきました ERROR 部分も修正し、わかりやすくなったかと思います。 本当に助かりました、ありがとうございます!
nak

2017/10/12 04:09

諸々ご確認&ご報告ありがとうございました。 解決されたのでしたら何よりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問