2008年01月09日

日付入力のチェックその6(まとめ)

前回まででようやく日付入力チェッククラスが形になってきたので、今回はこのクラスの簡単なテストをした結果とそれを市町村合併データベースアプリに組み込んだ際のメモ、加えて日付入力チェックということに関して今回考えたところを述べてみたいと思います。

まずクラスのチェックとして、与えられた日付(のようなモノ?)に対する出力の一覧です。
基本形
from年のみ20052005.1.1〜2005.12.31
from年月のみ2005.32005.3.1〜2005.3.31
from年月日2005.3.212005.3.21〜2005.3.21
from年月日 + to日のみ2005.3.4-212005.3.4〜2005.3.21
from年月日 + to年月のみ2005.3.4-2006.42005.3.4〜2006.4.4
from年月日 + to月日のみ2005.3.4-10.212005.3.4〜2005.10.21
from年月日 + to年月日2005.3.4-2005.6.212005.3.4〜2005.6.21
不正な値を含むパターン
from年月
2005.142006.2.1〜2006.2.28
from年月日
2005.3.352005.4.4〜2005.4.4
2005.14.12006.2.1〜2006.2.1
月日2005.14.352006.3.7〜2006.3.7
from年月日 + to日
to日2005.3.4-502005.3.4〜2005.4.19
from月2005.14.4-212006.2.4〜2006.2.21
from日2005.3.35-212005.3.21〜2005.4.4
from月日2005.14.35-212006.2.21〜2006.3.7
from月, to日2005.14.21-502006.2.21〜2006.3.22
from日, to日2005.3.35-502005.4.4〜2005.4.19
from月日, to日2005.14.35-502006.3.7〜2006.3.22
from年月日 + to月日
to日2005.3.4-10.352005.3.4〜2005.11.4
to月2005.3.4-14.202005.3.4〜2006.2.20
to月日2005.3.4-14.352005.3.4〜2006.3.7
from日2005.3.50-10.212005.4.19〜2005.10.21
from日, to日2005.3.50-10.352005.4.19〜2005.11.4
from日, to月2005.3.50-14.202005.4.19〜2006.2.20
from日, to月日2005.3.50-14.352005.4.19〜2006.3.7
from月2005.14.4-10.212005.10.21〜2006.2.4
from月, to日2005.14.4-10.352005.11.4〜2006.2.4
from月, to月2005.14.4-14.202006.2.4〜2006.2.20
from月, to月日2005.14.4-14.352006.2.4〜2006.3.7
from月日2005.14.50-10.212005.10.21〜2006.3.22
from月日, to日2005.14.50-10.352005.11.4〜2006.3.22
from月日, to月2005.14.50-14.202006.2.20〜2006.3.22
from月日, to月日2005.14.50-14.352006.3.7〜2006.3.22
from年月日 + to年月
to月2005.3.4-2006.142005.3.4〜2007.2.4
from日2005.3.50-2006.42005.4.19〜2006.5.20
from月2005.14.21-2006.42006.2.21〜2006.4.21
from日,to月2005.3.50-2006.142005.4.19〜2007.3.22
from月,to月2005.14.21-2006.142006.2.21〜2007.2.21
from月日2005.14.35-2006.42006.3.7〜2006.5.5
from月日,to月2005.14.35-2006.162006.3.7〜2007.5.5
from年月日 + to年月日
to日2005.3.4-2006.10.352005.3.4〜2006.11.4
to月2005.3.4-2006.14.202005.3.4〜2007.2.20
to月日2005.3.4-2006.14.352005.3.4〜2007.3.7
from日2005.3.50-2006.10.212005.4.19〜2006.10.21
from日, to日2005.3.50-2006.10.352005.4.19〜2006.11.4
from日, to月2005.3.50-2006.14.202005.4.19〜2007.2.20
from日, to月日2005.3.50-2006.14.352005.4.19〜2007.3.7
from月2005.14.4-2006.10.212006.2.4〜2006.10.21
from月, to日2005.14.4-2006.10.352006.2.4〜2006.11.4
from月, to月2005.14.4-2006.14.202006.2.4〜2007.2.20
from月, to月日2005.14.4-2006.14.352006.2.4〜2007.3.7
from月日2005.14.50-2006.10.212006.3.22〜2006.10.21
from月日, to日2005.14.50-2006.10.352006.3.22〜2006.11.4
from月日, to月2005.14.50-2006.14.202006.3.22〜2007.2.20
from月日, to月日2005.14.50-2006.14.352006.3.22〜2007.3.7

テストとしてはこれだけでは不十分で、0を明示的に与えた場合や7桁を超える数値、また年(西暦)に関しては上記ではテストしていません。

が、上記の一覧では期待通りの結果ですし、その他も一覧には載せていませんが手動テストの結果などから(今のところ)気期待通りに動いていることが確認できています。

ということでクラスは一応ちゃんと動いているということにして(^^;、これを本体に組み込みます。

まずcheckdate.phpというファイルをControllerフォルダの中に作成しそこに件のクラスを全部書きます。この時にこれまでのテストでは[〜]区切りで日付範囲を返していたperiodクラスのgetDateRange()メソッドを[-]区切りで返すように変更します。
public function getDateRange()
{
:
return $from."-".$to;
}

これは日付検索クラスと整合性をとるためです。そして本体?のgappei.phpでは頭でそれをrequireします。
require_once('checkdate.php');

つぎにsearch()メソッド内で以前は日付チェック関数を呼んでいた部分を次のように書き換えます。
$conditions['gdate'] = $this->_valid_date($conditions['gdate']);

$conditions['gdate'] = preg_replace("/[^0-9.-]/", "", $conditions['gdate']);

この部分ではその他のsearchコンディションのヴァリデートに加えて、数値・ドット・ハイフン以外を削除するだけにします。

そしてDecoratorパターンを用いて日付検索クラスをインスタンス化している部分で、日付チェッククラスを使用します。
if ($conditions['gdate'] <> '')
{
$vDate = new Period($conditions['gdate']);
$conditions['gdate'] = $vDate->getDateRange();

$this->cond = new GdateSearch($this->cond, $conditions);
}

これで一応組み込みは完了(のはず)です。でテストしてみました。
offset_error.png
「2005」とだけ入力してみたらいきなりエラー(--;。行数を確認するとlist()を使ってる部分でした。で、とりあえずブラウザで戻ってみると入力値の変換自体はきちんと行われているようだったので、とりあえずlist()の前に@をつけてエラーを抑制することにしておきました。

これでさしあたってエラーも出ず?日付で検索することが可能になりました。↑のエラーはlist()に渡す前に配列の数を数えるなりすればいいのかとおもいます。もしかしたらlist()の値と配列の要素数が異なる場合の書き方?とかがあるのかもしれませんがその辺はまだ調べていません。

で、6回に渡って書いてきた日付入力のチェックですが、一言で言えば「やはりメンドイ!」という感じです。単純に日付としての妥当性をチェックしてアラートでも出した方がスクリプト的にはすっきりすることでしょう。

この実装では不正な日付を極力自然に?解釈しようと試みましたが、果たしてこれが万人にとって自然かどうか?ということになるとかなり怪しい?というか、そもそも年月日の順で入力すること自体日本のローカルルールだったりもしますし、いずれにしろ日付入力に関しては決定打はないのかなぁ?と感じました。

ただ最終的にはクラスも作りGregorianToJDの代替関数もでっちあげたりで個人的にはいろいろと学ぶところは多かったようにおもいます。次回からはCodeIgniterに戻って(^^;、AJAXを組み込むことを考えていきます。
ラベル:codeigniter PHP
posted by ciallost at 21:42| Comment(36) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする