要素の多いフォームを作るのが面倒だったのでフォーム生成ライブラリ作ってみた
実際はSmarty使うだろうからおそらくもっと楽
つかいかた
・addXXX() で要素追加
・checkXXX() で入力チェック項目追加
・setValue() で初期値セット
・getForm() でフォーム要素のHTMLを配列を取得
・getConfirm() で確認画面用の表示用HTMLを配列を取得
・getInput() で送信用のhiddenのinputを取得
・getArray() でエスケープしていない値を配列で取得
・getError() で入力エラーメッセージを配列で取得
・hasError() エラーがあるか否か
機能
・$reqを引数に渡して初期値指定
・入力チェック
・1つの要素に対して最初に出たエラー以外出さない
・クロスサイトリクエストフォージェリ対策
入力チェック方法
・最小文字数/最小選択数
・最大文字数/最大選択数
・英数字か否か (Ctype)
・英字か否か (Ctype)
・制御文字か否か (Ctype)
・数字か否か (Ctype)
・空白以外の印字可能な文字か否か (Ctype)
・小文字か否か (Ctype)
・印字可能な文字か否か (Ctype)
・空白、英数字以外の出力可能な文字か否か (Ctype)
・空白文字か否か (Ctype)
・大文字か否か (Ctype)
・16進数を表す文字か否か (Ctype)
・空入力/未選択
・マッチ (preg)
デメリット
・デザインを適用しづらい
<?php require_once(dirname(__FILE__).'/Form.php'); $req = array_merge($_GET,$_POST); session_start(); $form = new Form(); // データセット $form->addText('name'); $form->addText('age'); $form->addRadio('gender',array('male'=>'男','female'=>'女')); $form->addCheckbox('hobby',explode(',','映画鑑賞,スポーツ,スポーツ観戦,音楽鑑賞,カラオケ・バンド,料理,グルメ,お酒,ショッピング,ファッション,アウトドア,ドライブ,旅行,アート,習いごと,語学読書,マンガ,テレビ,ゲーム,インターネット,ギャンブル,ペット,美容・ダイエット')); $form->addSelect('job',explode(',','IT関係,事務系,技術系,営業・企画系,クリエーター系,販売系,サービス業,ガテン系,役員・管理職,専門職,公務員,教員,自営業,アーティスト,フリーター,大学生・院生,専門学校生,主婦,求職中,その他'),'▼選択'); $form->addText('email'); $form->addTextarea('profile'); $form->addPassword('pass'); $form->addSubmit('確認'); // 入力チェック $form->checkEmpty('name','名前を入力してください'); $form->checkMax('name',20,'名前は20文字以内で入力してください'); $form->checkEmpty('age','年齢を入力してください'); $form->checkCtype('age','digit','年齢は半角数字のみで入力してください'); $form->checkEmpty('gender','性別を選択してください'); $form->checkMin('hobby',2,'趣味は最低2個以上選択してください'); $form->checkEmpty('job','職業を選択してください'); $form->checkEmpty('email','メールアドレスを入力してください'); $form->checkMatch('email','/^[a-zA-Z0-9\-_\.]+@[a-zA-Z0-9\-_\.]+$/','メールアドレスを正しく入力してください'); $form->checkEmpty('profile','自己紹介を入力してください'); $form->checkMax('profile',100,'自己紹介は100文字以内で入力してください'); $form->checkEmpty('pass','パスワードを入力してください'); $form->checkCtype('pass','alnum','パスワードは半角英数字で入力してください'); $form->checkMin('pass',4,'パスワードを4文字以上入力してください'); // チェック $mode = 'form'; // 完了画面 if(isset($req['mode']) && $req['mode']=='finish'){ // 初期値セット $form->setValue($req); // 入力チェック $form->checkToken('post_token','Tokenが一致しません'); $form->doCheck(); $form->delToken('post_token'); // 表示ページ $mode = 'finish'; if($form->hasError()){ $mode = 'error'; } // 確認画面 }elseif(isset($req['mode']) && $req['mode']=='confirm'){ // 初期値セット $form->setValue($req); $form->addHidden('mode','finish'); // 入力チェック $form->doCheck(); // トークンセット $form->addToken('post_token'); // 表示ページ $mode = 'confirm'; if($form->hasError()){ $mode = 'error'; } // 初期画面 }else{ // 初期値セット $form->setValue($req); $form->addHidden('mode','confirm'); } // 出力 $body = "<h1>{$mode}</h1>\n\n"; // 完了画面 if($mode=='finish'){ foreach($form->getConfirm() as $name=>$input){ $body .= sprintf("<b>%s:</b><br />\n%s<br />\n\n",$name,$input); } $body .= '<a href="">さいしょから</a><br />'."\n"; $body .= print_r($form->getArray(),1); // 確認画面 }elseif($mode=='confirm'){ $form->addHidden('mode','finish'); // 確認表示 foreach($form->getConfirm() as $name=>$input){ $body .= sprintf("<b>%s:</b><br />\n%s<br /><br />\n\n",$name,$input); } // 送信 $body .= '<form action="" method="post">'."\n"; $form->addHidden('mode','finish'); $form->addSubmit('送信'); $body .= $form->getInput(); $body .= '</form>'."\n\n"; // 戻る $body .= '<form action="" method="post">'."\n"; $form->addHidden('mode','edit'); $form->addSubmit('戻る'); $body .= $form->getInput(); $body .= '</form>'."\n\n"; // 初期画面 }else{ $form->addHidden('mode','confirm'); foreach($form->getError() as $err){ $body .= sprintf("# %s<br />\n",$err); } $body .= '<form action="" method="post">'."\n\n"; foreach($form->getForm() as $name=>$input){ $body .= sprintf("<b>%s:</b><br />\n%s<br /><br />\n\n",$name,$input); } $body .= "</form>\n"; } ?> <?='<?xml version="1.0" encoding="UTF-8"?>'."\n";?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="content-style-type" content="text/css" /> <style type="text/css"> body{ font-size: 12px; } </style> <title>フォーム生成</title> </head> <body> <?=$body;?> </body> </html>
久々の休みだ!
OpenSocial系の仕事、一応終わった!一応リリース!大変だった!