CakePHPのFlashエラーは出るが入力項目ごとのメッセージが出ないエラーの原因
CakePHP4で画面上部のフラッシュメッセージと入力ボックスに表示されるエラーメッセージ
Bakeで自動生成された Edit処理のソースを元に、少しだけ処理を追加したところ、入力エラーが発生しているのに、バリデーションのメッセージ(入力エラー)が表示されない、と言う不具合がありました。
上記の画像の「Flashメッセージ」は表示されるのですが、「バリデーションのメッセージ」が表示されないのです。
今回のこの不具合は、バリデーションエラー(入力チェックのエラー)は発生しているものの、正常な処理によるエラー処理のため(エラーログ等は出力されないため)、不具合の原因の特定に時間がかかったのですが、同じような不具合で悩んでいる方もあるのではないか、と思い記事を書きました。
原因は「エラーが発生しているときにリダイレクトしているため」でした。
この記事の内容は、CakePHP3、CakePHP4でも同じように処理できます。
ちなみに、フラッシュエラーに関しては下記にも記事を書いていますので、参考にしてください。
CakePHP4のフラッシュメッセージの表示場所、デザインを変更する方法を解説
CakePHP3 フラッシュ(FlashComponent)
https://book.cakephp.org/3/ja/controllers/components/flash.html
CakePHP4 フラッシュ(FlashComponent)
https://book.cakephp.org/4/ja/controllers/components/flash.html
エラーが発生したときの処理でリダイレクトをしていませんか?
CakePHP4の入力フォームで、バリデーションエラー(入力エラー)がある場合、画面上部に表示される Flashのエラーメッセージは表示されるものの、入力エラーがある項目の下にエラーメッセージは表示されない、という不具合の一つの原因をご紹介します。

今回の記事は、上記の不具合の原因の一例のご紹介です。
プログラムの文法には不具合はないため、原因が分かりにくいものです。
不具合の原因は多種多様です。
ですが、この記事で紹介したような不具合もあるよ!これで解決する方が一人でもいれば!という感じで書いています。
Bakeで自動生成されるデフォルトのソースコードを元に解説
下記は Bakeで自動生成されたソースコードの一部です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public function edit($id = null) { $topic = $this->Topics->get($id, [ 'contain' => [], ]); if ($this->request->is(['patch', 'post', 'put'])) { $topic = $this->Topics->patchEntity($topic, $this->request->getData()); if ($this->Topics->save($topic)) { $this->Flash->success(__('The topic has been saved.')); return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The topic could not be saved. Please, try again.')); } $this->set(compact('topic')); } |
入力エラーが発生すると
$this->Flash->error(__('The topic could not be saved. Please, try again.'));
の処理が実行されます。
ここで処理されたメッセージは、レイアウト「/templates/layout/default.php」に記述されている
= $this->Flash->render() ?>
で処理されて表示されます。
あわせて、入力項目の
echo $this->Form->control('topics_date');
で処理されて、バリデーションエラー(入力エラー)のメッセージが入力項目の下に表示されます。
デフォルトのソースコードを元に改変したソースコード
今回の不具合は、デフォルトの処理を少し改変し、ログを保存する処理を追加して下記のような処理にしていました。
この場合、バリデーションエラー(入力エラー)があった場合、Flashのメッセージは表示されるのですが、入力項目ごとのエラーメッセージは表示されません。
どこが間違っているか分かりますか?
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
try { $topic = $this->Topics->patchEntity($topic, $this->request->getData()); if ($this->Topics->save($topic)) { // ログを保存する $response = $this->Common->saveLog($topic); if(!$response){ throw new \Exception(__('The topic log could not be saved. Please, try again.')); } } else { throw new \Exception(__('The topic could not be saved. Please, try again.')); } $this->Flash->success(__('The topic has been saved.')); return $this->redirect(['action' => 'index']); } } catch (\Exception $e) { $this->Flash->error(__($e->getMessage())); return $this->redirect(['action' => 'edit', $id]); } |
不具合の原因は、17行目の「return $this->redirect(['action' => 'edit', $id]);」の部分になります。

上記の処理では、バリデーションエラーが発生した場合は 17行目でリダイレクトをしていますので、表示されている画面は、入力をする前の状態の画面が再度表示されているだけですので、入力項目ごとのエラーメッセージは表示されません。
ですが、16行目の「$this->Flash->error(__($e->getMessage()));」で処理している Flashメッセージに関しては、リダイレクトをしてもメッセージを受け取って表示をしてくれるのです。
これはこれで便利な機能なんですが、今回のような不具合の原因につながるのです。
処理の内容を確認すれば当たり前と言えば当たり前なんですが、Flashのエラーメッセージは表示されているため、リダイレクトされていることに気づきにくいんですよね。
処理は正しく行われており、バリデーションのエラーメッセージが表示されていない、
という不具合だと誤認してしまうのです。
そうするとなかなか不具合の原因に行き当たらないわけです。
プログラムの不具合はないけれど、入力項目ごとのエラーメッセージが表示されない。
そんな不具合が発生したときに原因に気づくきっかけになれば、と思っています。
CakePHP4の関連記事
CakePHPのpostlinkで生成した削除リンクをクリックしても処理が実行されない対処法CakePHP4系でJSONレスポンスの処理ではwithStringBodyを使う。3との違い解説
CakePHP4、CakePHP5の「warning: DebugKit is disabling...」の対処方法
MySQL+CakePHPのdate型、datetime型項目は「2999-12-31」までしか扱えない
CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法
CakePHP4のcake cache clear_allでPermission deniedはパーミッションの変更が必要
CakePHP4のクリエビルダーを使用してOR条件をAND条件でつなぐSQL文を作る方法
CakePHP4のController内でViewテンプレート、レイアウトの変更設定を記述する方法
CakePHP4から外部のデータベースにアクセスする方法解説
CakePHP4の数値項目は「like %10%」の部分一致検索(find select)はできない
その他の「CakePHP4」に関する記事一覧
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-

-
CakePHP3ログファイルへの出力・$this->log()、独自ログへの出力方法の解説
コントロール、モデルの変数の中身を見るときはログに出力する方法が有効です。$this->log()を利用すると変数だけじゃなく、連想配列、オブジェクトも簡単にログ出力ができます。
-

-
CakePHP3にWYSIWYGエディタのCKEditor4を設置、カスタマイズ方法を解説
WYSIWYGエディタであるCKEditor4をCDNを利用して簡単にCakePHP3に導入する方法とカスタマイズする方法を解説。CakePHP3にはページごとの振り分けを行うブロック化を利用する。
-

-
VirtualBoxにCakePHP3を設置。必要なCentOS、Apache、PHP、MySQL、Composerをインストールし設定する
VirtualBoxにCentOS、Apache、MySQL、PHPをインストールするところから初めてCakePHP3の開発環境を構築する手順を詳細解説。この記事1つで全ての設定が完了する。
-

-
CakePHP3の更新画面でUpload Plugin 3.0を使う方法、viewで使う方法解説・その3
CakePHP3でファイル、画像をアップロードするプラグイン、upload plugin 3を導入する手順を解説した記事。3部作のその3で記事を更新する際のファイルの取り回しなどについてを解説。
-

-
CakePHP3、CakePHP4のdatetime型カラムの日時の扱い。秒まで表示する方法
CakePHP3の日時カラムで秒まで扱う場合はdate()、strtotime()関数ではうまくいかない。CakePHP3であらかじめ用意された「i18nFormat()」を使用する。
-

-
CakePHP 2.3で saveの便利な使い方・サンプルソース付き
CakePHPのレコードを保存、更新する際に使う Saveを詳細解説します。
-

-
CakePHP4の規約外のカラムをキーにアソシエーション(テーブル連結)する方法
CakePHPで規定外のカラム名のキーを指定してアソシエーション(テーブル連結)をする方法を解説。アソシエーション名によってはミスが発生しやすい点もあるので注意も必要。
-

-
CakePHP4でcontrollerで実行したバリデーションエラーをmodelのにマージする方法
CakePHP4でcontrollerで実行したバリデーションの結果をModelのバリデーション結果に追加するメソッド「setError()」「setErrors()」の使い方の解説。
-

-
CakePHP3でcomposerを利用してライブラリ・プラグインをインストールする方法
CakePHP3でcomposerを使ってパッケージ(ライブラリ、プラグイン)をインストールする方法の解説。PHPを使うのはCakePHP3が初めてというような方への使い方から解説。
-

-
CakePHP3でデフォルトのソート条件を設定してユーザの選択肢たソート条件を有効にする方法
CakePHP3でデフォルトのソート条件を設定しつつ画面上でユーザがソート条件を選択したときもソート処理を実行させる方法を解説。ソート条件はページネーションの処理として実装。