003.詳細ページの記述方法
ここでは、
sources/prefecture_detail.phpについて説明します。
詳細ページの機能
ページの最上部に
ライブラリのインクルードが前項のようにありますので、それがまず記述されます。
そして
詳細ページの機能は以下のようになります。
1、一覧ページに戻ることができる
2、都道府県名を修正できる(確認画面つき)
3、都道府県を新規で追加できる(確認画面つき)
では個別に見ていきます。
1、一覧ページに戻ることができる
これは単純に
prefecture_listへのリンクを記述すればいいのかというと、そうでもありません。一覧ページからのリンクは
ページ情報が含まれますので、そのページに戻ったほうが、直感的に扱いやすいでしょう。
prefecture_detail.phpの
実行ブロックに、
$page = 0;
if(isset($_GET['page'])
&& cutil::is_number($_GET['page'])
&& $_GET['page'] > 0){
$page = $_GET['page'];
}
と記述があります。これは
ページ情報があれば$pageに設置ということです。この変数は
一覧に戻るのリンクに使用します。
一覧に戻るリンクはHTMLブロックに以下のように記述されています。
<a href="prefecture_list.php<?php echo_page(); ?>">一覧に戻る</a>
GETパラメータに
<?php echo_page(); ?>が記述されています。この関数は
function echo_page(){
global $page;
if($page > 0){
echo '?page=' . $page;
}
}
となっていて、もとの一覧ページに戻れるようになっています。
2、都道府県名を修正できる(確認画面つき)
これは
GET/POST引数で都道府県IDが指定された場合の処理になります。
まず、実行ブロックで
$prefecture_id = 0;
//中略
if(isset($_GET['pid'])
//cutilクラスのメンバ関数をスタティック呼出
&& cutil::is_number($_GET['pid'])
&& $_GET['pid'] > 0){
$prefecture_id = $_GET['pid'];
}
//$_POST優先
if(isset($_POST['prefecture_id'])
//cutilクラスのメンバ関数をスタティック呼出
&& cutil::is_number($_POST['prefecture_id'])
&& $_POST['prefecture_id'] > 0){
$prefecture_id = $_POST['prefecture_id'];
}
これで
$prefecture_idには
新規の場合は
0が、それ以外は
都道府県IDが代入されます。
さて
詳細ページは
状態というパラメータを持っています。
$_POST['func']に代入される値ですが、
確認画面の場合は
'conf'です。
追加/更新の場合は
'set'です。
新規は
'new'になり、
編集は
'edit'です。
これらを
$_POST['func']が
渡されたかどうかを判断して、
状態を決定します。
実行ブロックではその振り分けを行います。以下のコードです。
if(isset($_POST['func'])){
switch($_POST['func']){
case 'set':
if(!paramchk()){
$_POST['func'] = 'edit';
$err_flag = 1;
}
else{
regist();
//regist()内でリダイレクトするので
//ここまで実行されればリダイレクト失敗
$_POST['func'] = 'edit';
//システムに問題のあるエラー
$err_flag = 2;
}
case 'conf':
if(!paramchk()){
$_POST['func'] = 'edit';
$err_flag = 1;
}
break;
case 'edit':
//戻るボタン。
break;
default:
//通常はありえない
echo '原因不明のエラーです。';
exit;
break;
}
}
else{
if($prefecture_id > 0){
if(($_POST = $prefecture_obj->get_tgt(false,$prefecture_id)) === false){
$_POST['func'] = 'new';
}
else{
$_POST['func'] = 'edit';
}
}
else{
//新規の入力フォーム
$_POST['func'] = 'new';
}
}
コードを追いかけていくとわかりますが、まず
$_POST['func']が渡された場合は
パラメータのチェックを行います。
パラメータのチェックが必要なのは
確認画面もしくは
追加/更新の時です。以下の関数を呼び出します。
function paramchk(){
global $err_array;
$retflg = true;
/// 都道府県名の存在と空白チェック
if(ccontentsutil::chkset_err_field($err_array,'prefecture_name','都道府県名','isset_nl')){
$retflg = false;
}
return $retflg;
}
ここで呼び出している
ccontentsutil::chkset_err_field()関数はエラーチェック用のユーティリティ関数です
common/contents_func.phpに記述があります。
この最後の引数
'isset_nl'というのは
存在と空白のチェックです。
ccontentsutil::chkset_err_field()関数はこのパラメータによって
どういうエラーチェックを行うかを決めます。
'isset_nl'で
ccontentsutil::chkset_err_field()関数を呼び出した場合、以下のコードが実行されます。
case 'isset_nl':
//存在と空白チェック
if(!isset($_POST[$name])){
$err_array[$name] = "{$field}が見つかりません";
return true;
}
elseif($_POST[$name] == '' ){
$err_array[$name] = "{$field}は必須項目です";
return true;
}
break;
つまり
$err_array配列にエラー内容をセットします。エラーの表示を修正する場合は
common/contents_func.phpの
ccontentsutil::chkset_err_field()関数を直接修正してください。このファイルは
ユーティリティ的な関数が記述されてますが、
common/function.phpとは違って、
ライブラリの一部という意味合いは弱いファイルとなっています。
さて、IDが指定された場合の
データの読み込みですが、
//都道府県クラスを構築
$prefecture_obj = new cprefecture();
と
cprefectureクラスのインスタンスを構築し
if($prefecture_id > 0){
if(($_POST = $prefecture_obj->get_tgt(false,$prefecture_id)) === false){
$_POST['func'] = 'new';
}
else{
$_POST['func'] = 'edit';
}
}
と読み込んでいます。この処理はどういう処理かというと
$_POST変数の直接読み込んでいます。
$_POST変数は特殊なグローバル変数ですが、
読み込みオンリーというわけではありません。ですから配列内に値をセットすることも可能です。
このような形にすることで
DBから読んだ場合と
ユーザーがPOSTした場合を同じように扱えることになります。
そして、各コントロール(ここでは
都道府県のフィールドです)は
function echo_prefecture_name(){
global $err_array;
if(!isset($_POST['prefecture_name']))$_POST['prefecture_name'] = '';
$tgt = new ctextbox('prefecture_name',$_POST['prefecture_name'],'size="70"');
$tgt->show($_POST['func'] == 'conf');
if(isset($err_array['prefecture_name'])){
echo '<br /><span class="red">'
. cutil::ret2br($err_array['prefecture_name'])
. '</span>';
}
}
のように記述します。ここで出てくる
ctextboxはページャー同様
common/controls.phpに記述がある
inputクラスです。このクラスは
入力状態と
確認状態を表示することができます。
show()メンバ関数に
trueを渡すと
確認状態、
falseを渡すと入力状態、になります。
$tgt->show($_POST['func'] == 'conf');
と記述されていますので、
$_POST['func'] が'conf'の時はtrueという意味になります。
また
入力状態と
確認状態の違いは
操作ボタンにもあります。
function echo_switch(){
global $prefecture_id;
if($_POST['func'] == 'conf'){
$button = '更新';
if($prefecture_id <= 0){
$button = '追加';
}
$str =<<<END_BLOCK
<input type="button" value="戻る" onClick="javascript:set_func_form('edit','')"/>
<input type="button" value="{$button}" onClick="javascript:set_func_form('set','')"/>
END_BLOCK;
}
else{
$str =<<<END_BLOCK
<input type="button" value="確認" onClick="javascript:set_func_form('conf','')"/>
END_BLOCK;
}
echo $str;
}
この関数は
入力状態と
確認状態で表示を振り分けています。
最後に更新処理ですが
regist()関数を使います。
function regist(){
global $prefecture_id;
$dataarr = array();
$dataarr['prefecture_name'] = (string)$_POST['prefecture_name'];
$chenge = new cchange_ex();
if($prefecture_id > 0){
$chenge->update('prefecture',$dataarr,'prefecture_id=' . $prefecture_id);
cutil::redirect_exit($_SERVER['PHP_SELF'] . '?pid=' . $prefecture_id);
}
else{
$pid = $chenge->insert('prefecture',$dataarr);
cutil::redirect_exit($_SERVER['PHP_SELF'] . '?pid=' . $pid);
}
}
まず、赤くなっているところに注目してください。
cchange_exクラスのインスタンスを構築しています。このクラスは一覧表示のところの
削除のところでも紹介しました。
updateやinsertもこの関数を使います。
使い方ですが、
$dataarr['prefecture_name'] = (string)$_POST['prefecture_name'];
のように連想配列を作って、
updateやinsert関数に渡します。この配列は
$arr['フィールド名'] = 値となる連想配列です。この例では
'prefecture_name'フィールドだけですが、通常はもっとたくさんのフィールドを修正、追加します。
そんな場合は
$dataarr['hoge'] = (string)$_POST['huga'];
$dataarr['hogehoge'] = (int)$_POST['hogehoge'];
のようにします
(string)や(int)は必要です。この関数は内部で
値の型を知らべて、形に合ったSQL文を作成します。特に、番号は必ず
(int)を付けましょう。
3、都道府県を新規で追加できる(確認画面つき)
追加処理は
更新処理とほとんど変わりません。
regist()関数で
idが0の場合は
cchange_ex::insert()関数を読んでいます。