HTML のフォームで「入力画面 → 確認画面 → 完了画面」のような流れを目にする機会は多い。今回は CodeIgniter の form_validation + Smarty でそれを実現する。
確認画面 → 完了画面の間は,session で値を渡すこともできなくはないが,CodeIgniter ではセッションデータを全部クライアントサイド (cookie) に持たせるので hidden と大差ないしちょっと怖い。ということで今回は input の hidden で実装する。
ただし,この方法はファイルを添付するようなフォームには使えない。他にもっとスマートな方法があれば教えてほしい。
コントローラで XSS 対策 (って言えば良いんですか?) をしておけば,Form ヘルパの form_open() 関数または form_hidden() 関数を使って
<?php echo(form_hidden($_POST)); ?>
のようにできなくもないが,それはビューで行ないたいのでこの方法は採用しない。
それではまず,form_validation を継承して自前のライブラリを作る。
$ vi system/application/libraries/MY_Form_validation.php
<?php defined('BASEPATH') or die('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation {
function __construct($config = array()) {
parent::__construct($config);
}
// フォームから送られた値を連想配列で返す
function get_values() {
$result = array();
foreach ($this->_field_data as $key => $val) {
if (!is_array($val['postdata']))
$result[$key] = $val['postdata'];
else
$result[$key] = implode("\0", $val['postdata']);
}
return $result;
}
}
get_values() は validation 済みの値を連想配列で返すメソッドである。
そしてコントローラで validation を行ない,成功すれば確認画面を表示する。set_rules() は確認画面も完了画面も同じ内容のはずなので,以下のように,コントローラにそれ用のプライベートメソッドを作っておけば良いだろう。
function _set_validation() {
$this->form_validation->set_rules(...);
:
}
コントローラのメソッドは次のようになる。
function index() {
$mode = $this->input->post('mode');
// 確認画面
if ($mode == 'confirm') {
$this->_set_validation();
if ($this->form_validation->run() == true) {
$this->data['hidden_list'] = $this->form_validation->get_values();
$this->smarty_parser->parse('ci:<確認画面>.tpl', $this->data);
return;
}
}
// 送信
if ($mode == 'submit') {
$this->_set_validation();
if ($this->form_validation->run() == true) {
: // 送信処理
$this->data['hidden_list'] = $this->form_validation->get_values();
$this->smarty_parser->parse('ci:<完了画面>.tpl', $this->data);
return;
}
}
// 入力画面
$this->smarty_parser->parse('ci:<入力画面>.tpl', $this->data);
}
なお,$this->data はテンプレートパーサに値を渡すためのコントローラのメンバ変数 (var $data;) だが,メソッドのローカル変数でも別に構わない。
入力画面のビューは次のようになる。
<form method="post">
<input type="hidden" name="mode" value="confirm" />
:
確認画面のビューでは,入力画面から受け取った値を hidden に挿入する。
<form method="post">
<input type="hidden" name="mode" value="submit" />
{foreach from=$hidden_list key="key" item="value"}
<input type="hidden" name="{$key}" value="{$value|escape}" />
{/foreach}
:
“|escape” は HTML のエスケープを行なう Smarty の修飾子である。
確認画面のビューでユーザの入力値を表示するには,
お名前: {$hidden_list.name|escape}
または
お名前: <?php echo set_value('name'); ?>
のようにすれば良い。
以上で確認画面を作成できた。
ただし,
<input type="text" name="options[]"...
のように配列で渡された場合の動作確認はしていない。
それから,ユーザガイドの フォーム・バリデーション(検証) > フィールド名の指定に配列を使う に
フォームの再表示の時はこうです:
<input type="text" name="options[]" value="<?php echo set_value('options[]'); ?>" size="50" />
と書かれているが,これは実際には正常に動作しない。
コメント