2011/3/27
昔は、よく見かけた「足跡を残す」を作成してみます。
完成イメージは、「足跡」を参照願います。足跡を残して頂けると、幸いです。
足跡を残すシステムの作成!設計メモ
<論理設計>
- 環境設定
- WEBサーバ:Apache2
- DBサーバ:MySQL5
- 開発言語:PHP5、
JavaScript(JQUERY)
- 文字コード:UTF8
- 動作対象:パソコンブラウザ
- システム構成図

- 使用ライブラリ
クライアント
- jquery-1.4.4.min.js
ここ
- jquery-ui-1.8.10.custom.min.js
ここ
- exvalidation.js
- exchecker-ja.js
ここ
- 情報検討
- 投稿No
- 投稿者名
- 投稿日時
- 投稿内容
- 返信内容
- 禁止IPアドレス
- 画面検討
- 機能検討
- 投稿登録
- 返信登録
- 投稿一覧表示
- 投稿内容チェック機能
- 投稿禁止機能
- 投稿削除機能
<物理設計>
- DB
- 名称:足跡
- ID:footprint
- SQL:CREATE DATABASE `footprint` ;
- テーブル
- 名称:足跡
- ID:footstamp
- 投稿No:cont_no INT 10 A_I
- 投稿者名:cont_name VARCHAR 40
- 投稿日時:cont_date TIMESTAMP 10
- 投稿内容:cont_body VARCHAR 200
- 返信内容:cont_res VARCHAR 200
- IPアドレス:ip_address VARCHAR 20
- SQL
CREATE TABLE `footprint`.`footprint` (
`cont_no` INT( 10 ) NOT NULL AUTO_INCREMENT COMMENT '投稿No',
`cont_name` VARCHAR( 40 ) NOT NULL COMMENT '投稿者名',
`cont_date` TIMESTAMP NOT NULL COMMENT '投稿日時',
`cont_body` VARCHAR( 200 ) NOT NULL COMMENT '投稿内容',
`cont_res` VARCHAR( 200 ) NULL COMMENT '返信内容',
`ip_address` VARCHAR( 20 ) NOT NULL COMMENT 'IPアドレス',
PRIMARY KEY ( `cont_no` )
) ENGINE = InnoDB;
- 名称:禁止IP
- ID:badip
- IPNo:ip_no INT 11 A_I
- IPアドレス:ip_address VARCHAR 20
- SQL
CREATE TABLE `footprint`.`badip` (
`ip_no` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`ip_address` VARCHAR( 20 ) NOT NULL
) ENGINE = InnoDB COMMENT = '禁止IPアドレス';
- インターフェース
サーバ、クライアントのインターフェースは、JSONで行う。
[{"cont_no":"62",
"cont_name":"xxxxxx",
"cont_date":"xxxxxx",
"cont_body":"xxxxxx",
"cont_res":"xxxxx",
"ip_address":"xxxxx"
}]
- 画面
<投稿画面>
名前:40文字以下、禁止文字チェック
足跡:3文字以上200文字以下、必須入力、禁止文字チェック
足跡を残すボタン押下で、入力内容チェック後サーバに送信する。
<返信画面>
内容:3文字以上200文字以下、必須入力、禁止文字チェック
返信するボタン押下で、入力内容チェック後サーバに送信する。
- 機能詳細
投稿登録
- 投稿登録ダイアログ表示
ダイアログID:cdialog1
$(function(){
//ダイアログ定義
$('#cdialog1').dialog({
autoOpen: false,
modal: true,
width: 400,
//show:"fadeIn(5000)",
buttons: {
"足跡を残す": function() {
$("#fm1").submit();
},
"キャンセル": function() {
$(this).dialog("close");
}
}
});
//入力内容チェック
$("#fm1").exValidation({
rules: {
cont_name: "min0 max40 kin",
cont_body: "required min0 max200 kin"
},
errInsertPos: 'after',
errPosition: 'fixed',
customSubmit:fm1submit
});
//ダイアログ表示
$('#push_footprint').click(function() {
//入力エリア初期化
$('#cont_name').attr('value','');
$('#cont_body').attr('value','');
//ダイアログオープン
$('#cdialog1').dialog('open');
});
});
function fm1submit(){
//入力データ送信
$.post("setfootprint.php",{
cont_name:$('#cont_name').attr('value'),
cont_body:$('#cont_body').attr('value')
},
function(ret){
if(ret){
alert(ret);
}
}
);
$('#cdialog1').dialog("close");
}
//HTML
<DIV id="cdialog1" title="足跡投稿" style="display:none">
<form id="fm1">
<div style="border: 1px #FF6600 solid;padding:10px 10px 10px 10px;width:380px">
<table>
<tbody>
<tr>
<td>お名前</td>
<td><input type="text" value="" name="cont_name" id="cont_name" size=20>さん</td>
</tr>
<tr>
<td>足跡</td>
<td><TEXTAREA rows="5" cols="40" name="cont_body" id="cont_body"></TEXTAREA></td>
</tbody>
</table>
</div>
</form>
</DIV>
ポイント:
exValidationに都合の良い禁止文字チェックが無いので、
無ければ、作れば良い!!
exchecker-ja.jsに下記のチェックを追加
kin: [
'記号([][&;`,\\\'"|*?~<>^(){}.$_:)以外の文字を入力してください',
function(txt, t) {
if ( txt && txt.length>0 ) {
if ( /[&;`',\\\"|*?~<>^(){}.$_:]/.test(txt) ) {
return false;
} else {
return true;
}
} else {
return true;
}
}
],
- 足跡登録
POSTパラメータで渡された、名前、足跡を足跡テーブルに登録する。
<サーバ処理>
//共通環境設定
require_once("config.php");
try{
//DB接続
$db = new PDO($dsn,$uid,$passwd);
$nowencoding = "utf8";
$sqlstr="SET NAMES ".$nowencoding;
$db->query($sqlstr);
mb_language("JA");
//ポストパラメータ取得
if(isset($_POST['cont_name'])){
$cont_name=$_POST['cont_name'];
if($cont_name==""){
$cont_name="匿名希望";
}
}else{
die("SYSTEM ERROR WRONG PARAMETER cont_name");
}
if(isset($_POST['cont_body'])){
$cont_body=$_POST['cont_body'];
}else{
die("SYSTEM ERROR WRONG PARAMETER cont_body");
}
//IPアドレスを取得
$ipAddress = $_SERVER["REMOTE_ADDR"];
//メイン処理
//連続投稿チェック
if(check_ip($ipAddress,$db)){
die("連続投稿されました。");
}
//書き込
if(insert_footprint($cont_name,$cont_body,$ipAddress,$db)){
echo "足跡を頂きました。ありがとうございます。";
}
$db = null;
} catch(PDOException $e){
die("SYSTEM ERROR " . $e->getMessage());
}
exit;
/**
* IPアドレスチェック
*
* @access public
* @return true:不正アクセス false:正常
*/
function check_ip($ipAddress,$db){
try{
$sqlstr="";
$sqlstr.="select count(*) as cnt from badip ";
$sqlstr.="where ip_address='" . $ipAddress . "'";
$rs=$db->query($sqlstr);
if($rs){
$row=$rs->fetch(PDO::FETCH_ASSOC);
$cnt=$row['cnt'];
$rs=null;
if($cnt>0){
return true;
}
$sqlstr="";
$sqlstr.="select cont_date,count(*) as cnt from footprint ";
$sqlstr.="where ip_address='" . $ipAddress . "'";
$rs=$db->query($sqlstr);
$row=$rs->fetch(PDO::FETCH_ASSOC);
$cnt=$row['cnt'];
if($cnt>0){
$cont_date=$row['cont_date'];
}else{
$cont_date="";
}
$rs=null;
if($cont_date==""){
return false;
}
//現在日付を取得しタイムスタンプに変換
$today1 = getdate();
$timestamp=chg_timestamp($today1);
//取得日付をタイムスタンプに変換
$today2 = date_parse($cont_date);
$get_timestamp=chg_timestamp($today2);
//3秒以内で投稿されている場合、連続投稿と判定
$get_timestamp=$get_timestamp+3;
if($timestamp<=$get_timestamp){
//連続投稿
return true;
}else{
return false;
}
}else{
return false;
}
} catch(PDOException $e){
die("SYSTEM ERROR " . $e->getMessage());
}
}
function chg_timestamp($today){
if(isset($today['mon'])){
$today_month = $today['mon'];
$today_day = $today['mday'];
$today_hours = $today['hours'];
$today_minutes = $today['minutes'];
$today_second = $today['seconds'];
}else{
$today_month = $today['month'];
$today_day = $today['day'];
$today_hours = $today['hour'];
$today_minutes = $today['minute'];
$today_second = $today['second'];
}
$today_year = $today['year'];
$timestamp = mktime($today_hours, $today_minutes, $today_second,
$today_month, $today_day, $today_year);
return $timestamp;
}
/**
* 足跡作成
*
* @access public
* @return true:書き込み成功
*/
function insert_footprint($cont_name,$cont_body,$ipAddress,$db){
try{
$sts=false;
$sqlstr="insert into footprint ";
$sqlstr.="(";
$sqlstr.="cont_name,";
$sqlstr.="cont_body,";
$sqlstr.="ip_address";
$sqlstr.=")";
$sqlstr.=" values ";
$sqlstr.="(";
$sqlstr.="'" . $cont_name . "'";
$sqlstr.=",";
$sqlstr.="'" . $cont_body . "'";
$sqlstr.=",";
$sqlstr.="'" . $ipAddress . "'";
$sqlstr.=")";
//トランザクション開始
$ret = $db->beginTransaction();
$ret = $db->query($sqlstr);
//コミット
$ret = $db->commit();
$sts=true;
return $sts;
} catch(PDOException $e){
$ret = $db->rollback();
die("SYSTEM ERROR " . $e->getMessage());
}
}
- 足跡一覧表示
足跡テーブルより、データを取得して一覧表示を行う。
<クライアント処理>
function get_footprint(){
url="getfootprint.php";
$.getJSON(url,{
dmy:Math.floor(Math.random()*1000),
pageline:$('#inpageline').attr('value'),
nowp:$('#nowp').text()
},showdata);
}
function showdata(lddat){
if(lddat){
$('#list_area').empty();
var tlist="";
for (i = 0; i < lddat.length; i++) {
tlist="<tr>";
tlist+="<td>" + lddat[i].cont_no + "</td>";
tlist+="<td>" + lddat[i].cont_date + "</td>";
tlist+="<td>" + lddat[i].cont_name + "</td>";
tlist+="<td>" + lddat[i].cont_body + "</td>";
if(lddat[i].cont_res){
tlist+="</tr>";
tlist+="<tr>";
tlist+="<td colspan=4>";
tlist+=lddat[i].cont_res;
tlist+="</td>";
}
tlist+="</tr>";
$('#list_area').append(tlist);
}
}else{
var nowp=($('#nowp').text() - 0);
nowp=nowp-1;
if(nowp&l;t1){
nowp=1;
}
$('#nowp').text(nowp);
return;
}
}
ポイント:
$('#nowp').text() - 0
-0することで、数値として扱う。
$('#list_area').empty();
子要素を空にする。
- 足跡一覧表示
<サーバ処理>
//共通環境設定
require_once("config.php");
try{
//DB接続
$db = new PDO($dsn,$uid,$passwd);
$nowencoding = "utf8";
$sqlstr="SET NAMES ".$nowencoding;
$db->query($sqlstr);
mb_language("JA");
$start=0;
$pagecnt=30;
//GETパラメータ取得
if(isset($_GET['pageline'])){
$pagecnt=$_GET['pageline'];
}
if(isset($_GET['nowp'])){
$nowp=$_GET['nowp'];
$start=($nowp - 1)*$pagecnt;
}
//IPアドレスを取得
$ipAddress = $_SERVER["REMOTE_ADDR"];
$sqlstr="";
$sqlstr.="SELECT * from footprint ";
$sqlstr.="ORDER BY cont_no DESC ";
$sqlstr.="LIMIT " . $start . "," . $pagecnt;
$rs=$db->query($sqlstr);
while( $row=$rs->fetch(PDO::FETCH_ASSOC) ){
$list[]=$row;
}
$rs=null;
if(isset($list)){
$hash = json_encode($list);
}else{
$hash = "";
}
$db = null;
echo $hash;
} catch(PDOException $e){
die("SYSTEM ERROR " . $e->getMessage());
}
exit;
ポイント:
json_encode($list);
配列をJSONに変換する。
- その他の処理
ページング処理:
一ページあたりの表示件数:リストボックスで切り替え
前ページ:前ページの表示
次ページ:次ページの表示
足跡返信画面は、Noクリックで表示
//返信ダイアログオープン
$('#list_area th').live("click",function() {
$('#cont_no').attr('value',$(this).text());
$('#disp_no').text($(this).text());
$('#cont_name2').text($(this).next().next().text());
$('#cont_body2').attr('value','');
$('#cont_password').attr('value','');
//ダイアログオープン
$('#cdialog2').dialog('open');
});
パスワードで認証して、書き込み可能にする。
パスワードは、内緒
|