エラーメッセージを出すタイミング

ちょっとここ数日気になってやりかたを調べてたのでメモメモ。


Webサイトのフォームで、入力エラーがあるとエラーメッセージを出す必要がある。
必須項目に値が入力されていなかったら、エラーメッセージを出すやつ。
よく日本のサイトでは入力 -> 確認 -> 完了というながれで、
海外は入力 -> 完了というのが多いらしい。
間に確認を挟む、挟まないはサイトや目的によって異なるが、とりあえずは挟んでおく事とした。


チェックは入力 -> 確認の間で入力チェック、確認 -> 完了の間で行う。
アクションが indexAction、confirmAction、finishAction があるとしたら、

  • indexAction -> 入力
  • confirmAction -> 確認
  • finishAction -> 完了 (DBなどに登録)

となる。
入力チェックはそれぞれ confirmAction、finishAction で行う。

<?php
private function confirmAction()
{
    $param = $this->_getParam('hoge');
    // 入力チェック
    // 本来は Zend_Validate とかを使うけど、今回は省略
    if ($param === '') {
        $this->_setParam('error', 'エラー!');
    }
}

めちゃくちゃ端折っているけど、入力にエラーがあると、_setParam() で
エラーをテンプレートにセットして、テンプレート側で表示する。
confirm.tpl

{if $error}
  {$error|escape}
{/if}

こうすると、確認画面で入力された値にエラーがあるとエラーと表示される。



個人的には確認画面に表示されて、入力画面にリンクなりフォームのボタンで戻るという方法は、
ユーザ側が戻るという操作が増えるので好きじゃない。
エラー表示は入力画面に表示させたい。

入力画面にエラーを表示するには

_foward() を使用して indexAction() に戻す、あるいは _redirect() でリダイレクトを行う方法しか思いつかなかった。

<?php
public function indexAction()
{
    if ($this->_getParam('error')) {
        $this->assign('error', $this->_getParam('error'));
    }
}
public function confirmAction()
{
    $param = $this->_getParam('hoge');
    // 入力チェック
    // 本来は Zend_Validate とかを使うけど、今回は省略
    if ($param === '') {
        $this->_setParam('error', 'エラー!');
        $this->_foward('index');
        return;
    }
}

このままでは confirmAction() で呼ばれる postDispatch() も動作してしまう。
自作の Layout 機能は postDispatch() でテンプレートを呼んでいるので、
confirm.tpl と index.tpl が読み込まれる。

_forward($action, $controller = null, $module = null, array $params = null): 別のアクションを実行します。preDispatch() の中でコールすると、 リクエストされていたアクションは飛ばされ、 新しいアクションを実行します。それ以外の場合は、 現在のアクションの処理を済ませた後で _forward() で指定したアクションを実行します。

http://framework.zend.com/manual/ja/zend.controller.action.html#zend.controller.action.utilmethods

ドキュメントには現在のアクションが終わった後に新しいアクションを実行するとある。
メソッドが呼ばれる順番は以下のようによばれる。

  1. confirmAction() 起動
  2. _foward() で indexAction() に遷移の指示
  3. confirmAction() の postDispatch() が起動
  4. indexAction() が起動
  5. indexAction() の postDispatch() が起動


ちょっとダサイ方法だけど、_fowad() をラップするメソッドを作って、
そのメソッドが呼ばれたら、フラグを立てて、postDIspatch() でそのフラグが
立っていたら、テンプレートを呼ばないようにする。
これで、confirm.tpl と index.tplの 2 つが読み込まれなくなる。


これで入力画面にエラーメッセージが表示されるようになったが、
URIhttp://example.com/index/confirm となってしまう。。。


もっと良い方法ないのかなぁ。
CakePHPSymfony ではどうやるんだろう。。。
ちなみに Symfony が使われている Yahoo! Bookmark のブックマーク開設時の設定画面では
入力画面の次の画面にエラー画面が出て、リンクで入力画面に戻していた。


そもそも入力画面にエラーメッセージを出したいという要望はあまりないのかなぁ。