掲示板2 - PHPとPostgreSQLの連携入門
目次
掲示板2
データベースの機能を活かして、書き込み時刻・記事削除・ソート機能などを追加します。テーブルの作成
以下のようなテーブルを「pgbbs2」という名前で作成してください。列名 | データ型その他 | 説明 |
---|---|---|
no | serial primary key | 記事番号 |
name | text | 名前 |
title | text | 題名 |
contents | text | 内容 |
time | timestamp default 'now' | 書き込み時刻 |
delkey | text | 削除キー |
# create table pgbbs2(no serial primary key, name text, title text, contents text, time timestamp default 'now', delkey text);
カラム no の serial 型とは、自動的に増加して行く数値型です。デフォルトでは 1 から始まり 1 ずつ増加します。カラム time はインサートしたときに指定されていなければ default の値 'now'、つまり現在時刻が挿入されます。
プログラムの作成
以下のソースを入力してください。但しdbname=postgres user=postgres password=postgres
上記の部分は、テーブルを作成したDB名、ユーザ名、パスワードに変更してください。
<?php
$con = pg_connect("dbname=postgres user=postgres password=postgres");
if ($_POST['write']) {
$name = get_form($_POST['name']);
if (!$name) $name = "名無しさん";
$title = get_form($_POST['title']);
if (!$title) $title = "無題";
$contents = get_form($_POST['contents']);
if (!$contents) error("本文を入力してください");
$delkey = get_form($_POST['delkey']);
$expire = time() + 3600 * 24 * 30;
setcookie("name", $name, $expire);
setcookie("delkey", $delkey, $expire);
pg_query($con, "insert into pgbbs2(name,title,contents,delkey) values('$name','$title','$contents','$delkey')");
} else {
$name = $_COOKIE['name'];
$delkey = $_COOKIE['delkey'];
}
if ($_POST['delete']) {
$no = get_form($_POST['no']);
$delkey = get_form($_POST['delkey']);
$rs = pg_query($con, "delete from pgbbs2 where no=$no and delkey='$delkey'");
if (pg_affected_rows($rs) == 0) error("記事削除に失敗しました");
}
// フォームの文字列を取得する
function get_form($str) {
$str = pg_escape_string(htmlspecialchars($str));
$str = ereg_replace("\n|\r|\r\n", "<br>", $str);
return $str;
}
// エラー表示して終了
function error($msg) {
print "<p><font color='red'>$msg</font></p>\n";
exit();
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>掲示板2</title>
</head>
<body>
<form method="post" action="pgbbs2.php">
お名前:<input type="text" name="name" value="<?php print $name ?>"><br>
題 名:<input type="text" name="title"><br>
削除キー:<input type="password" name="delkey" value="<?php print $delkey ?>"><br>
<textarea name="contents" cols="60" rows="5"></textarea><br>
<input type="submit" name="write" value="送信">
</form>
<hr>
<form method="post" action="pgbbs2.php">
記事番号:<input type="text" name="no">
削除キー:<input type="password" name="delkey" value="<?php print $delkey ?>">
<input type="submit" name="delete" value="記事削除">
</form>
<?php
$rs = pg_query($con, "select * from pgbbs2 order by no desc");
while ($row = pg_fetch_array($rs)) {
$time = substr($row['time'], 0, 19);
print "<hr>No.{$row['no']} <strong>{$row['title']}</strong>";
print " 投稿者:{$row['name']} 投稿日時:$time";
print "<br><br>{$row['contents']}\n";
}
pg_close($con);
?>
</body>
</html>
入力が終わったら「pgbbs2.php」というファイル名で保存、サーバにアップロードし、実行してみてください。ソースの解説
if ($_POST['write']) {
送信ボタンが押されたとき if ブロック内の処理を実行します。
$name = get_form($_POST['name']);
if (!$name) $name = "名無しさん";
$title = get_form($_POST['title']);
if (!$title) $title = "無題";
$contents = get_form($_POST['contents']);
if (!$contents) error("本文を入力してください");
$delkey = get_form($_POST['delkey']);
フォームに入力された文字列から名前を $name、題名を $title、内容を $contents、削除キーを $delkey に get_form 関数(後述)で変換して格納します。名前または題名が空だった場合はデフォルトの値を代入し、内容が空だった場合は error 関数(後述)によってエラー表示して終了します。
$expire = time() + 3600 * 24 * 30;
setcookie("name", $name, $expire);
setcookie("delkey", $delkey, $expire);
クッキーをセットしている部分です。クッキーの有効期限を 3600(秒)×24(時間)×30(日)、つまり約1ヶ月後にし、setcookie 関数によって name と delkey という名前のクッキーをセットしています。
pg_query($con, "insert into pgbbs2(name,title,contents,delkey) values('$name','$title','$contents','$delkey')");
フォームで送信された名前・題名・内容・削除キーをテーブル pgbbs2 に挿入します。指定していない列のうち、no は serial 型なので現在の最大記事番号+1が自動的にセットされ、time には default の値つまり現在時刻がセットされます。
} else {
$name = $_COOKIE['name'];
$delkey = $_COOKIE['delkey'];
}
送信ボタンが押されていなければ、前回にセットされたクッキー値から名前と削除キーを取得します。
if ($_POST['delete']) {
$no = get_form($_POST['no']);
$delkey = get_form($_POST['delkey']);
$rs = pg_query($con, "delete from pgbbs2 where no=$no and delkey='$delkey'");
if (pg_affected_rows($rs) == 0) error("記事削除に失敗しました");
}
記事削除ボタンが押されたら、削除する記事番号を $no、削除キーを $delkey に代入して指定された記事を削除するSQL文を実行します。削除された行がなければ(pg_affected_rows 関数は削除された行数を返す)、エラーを表示して終了します。
function get_form($str) {
$str = pg_escape_string(htmlspecialchars($str));
$str = ereg_replace("\n|\r|\r\n", "<br>", $str);
return $str;
}
フォームの文字列をDBに登録するために加工する部分は、何度も呼び出されるので関数化してあります。タグの無効化と特殊文字のエスケープを行い、改行を<br>に変換しています。
function error($msg) {
print "<p><font color='red'>$msg</font></p>\n";
exit();
}
エラー文字列を赤色で出力して終了する関数です。
お名前:<input type="text" name="name" value="<?php print $name ?>"><br>
題 名:<input type="text" name="title"><br>
削除キー:<input type="password" name="delkey" value="<?php print $delkey ?>"><br>
<textarea name="contents" cols="60" rows="5"></textarea><br>
名前と削除キーは、クッキーで値が取得できればその値を表示します。
$rs = pg_query($con, "select * from pgbbs2 order by no desc");
テーブル pgbbs2 の内容を全て記事番号 no の逆順で読み出します。
$time = substr($row['time'], 0, 19);
timestamp 型はμ秒までの精度があるので、年月日・時分秒まででカットするために substr 関数を呼び出しています。