いよいよ簡易版とはいえ、一つのアプリケーションを構築してみましょう!PHPによる時間の取得、ファイルへの書込、ファイルからの読み込み、データの加工など被とおりの要素が詰まったものが掲示板です。

まず、知っておきたい便利コマンドを列記します。
1. POSTでデータを送った後、ブラウザの再読込をしてもデータが書かれない方法
PHP header()関数
2. CSVのルールに従ってファイルへ書く、ファイルに書かれたデータを配列に格納する
PHP fgetcsv()関数、fputcsv()関数
※PHP4の場合、fputcsv関数がありませんので事前に準備する必要があります。(ダウンロードして、fputcsv_php4.phpに名前を変更して下さい)

また、掲示板ということでプログラマーとして絶対に気を付けるべき事は次の2つです。

  • 悪意のあるコードを書かれても向こうにする XSS対応
  • 書き込まれたファイルをブラウザからアクセスされない処置 情報漏洩対策

※情報漏洩は掲示板であれば基本、問題視されません。書かれた内容は全て公開するシステムが掲示板なのですから。よって、今回は何もしていませんが、ディレクトリを分けて、いつでも .htaccess で制御できるようにしています。

今回は文字コードを全てUTF-8で統一しました。UTF-8で統一するための .htaccess の記述はこんな感じです。

php_value default_charset UTF-8
php_value mbstring.language Japanese
php_value mbstring.internal_encoding UTF-8
php_flag mbstring.encoding_translation OFF
php_value mbstring.http_input auto
php_value mbstring.http_output pass
php_flag magic_quotes_runtime Off
php_flag magic_quotes_gpc Off

最期に、PHPで吐き出すHTML構文は、id や class を付けてCSSで体裁とを整えるようにしておきましょう。


簡易掲示板 PHP5版

<?php
/***********************************************************
**    PHPマスター bbs.php  Version 01 PHP5
**    Copyright(c) 2010 Inter Space Planning.
**    http://blog.info-square.jp/scriptmaster/
*************************************************************/
setlocale(LC_ALL,"ja_JP.UTF-8");
//
$title   = "簡易掲示板";
$datadir = "./data/";
$myfile  = $datadir."data.txt";
//
$reload  = $_SERVER["SCRIPT_NAME"];
$act = $_POST['act'];
$nam = $_POST['b_name'];
$bod = $_POST['b_body'];
if($act) {
  if(!$nam) { $errormess["name"] = "名前が未入力です"; }
  if(!$bod) { $errormess["body"] = "本文を書いて下さい"; }
  if(!isset($errormess)) {
    $today = date("Y/m/d H:i:s");
    $newdata = array($today,$nam,$bod);
    $csv[] = $newdata;
    $fp = fopen($myfile,"r");
    while($csv[] = fgetcsv($fp,"1024")) { }
    fclose($fp);
    $fp = fopen($myfile,"w");
    foreach($csv as $line) {
      fputcsv($fp,$line);
    }
    fclose($fp);
    header("Location: $reload", true, 303);
  }
}
?>
<!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" />
<link rel="stylesheet" href="style.css" />
<title><?php echo $title; ?></title>
</head>
<body>
<div id="bbsform">
<h1><?php echo $title ?></h1>
<form action="<?php echo $reload ?>" method="post">
<input type="hidden" name="act" value="regist">
お名前:
<input type="text" name="b_name" size="30" value="<?php echo $nam; ?>" /><br />
<textarea name="b_body" rows="10" cols="50"><?php echo $bod; ?></textarea><br />
<input type="submit" value="登録" class="mybutton" />
<input type="reset" value="書き直し" />
<input type="button" value="再読込" onClick="location.href='<?php echo $reload; ?>'" />
</form>
<?php
if(isset($errormess)) {
  echo "<ul class='err'>\n";
  foreach ($errormess as $key => $val) { echo "<li>".$val."</li>\n"; }
  echo "</ul>\n";
}
?>
</div>
<div id="bbslog">
<?php
$fp = fopen($myfile,"r");
while($csv[] = fgetcsv($fp,"1024")) { }
fclose($fp);
for($i=0; $i<count($csv)-1; $i++) {
  echo "<div class='date'>".$csv[$i][0]."</div>\n";
  echo "<div class='name'>".htmlspecialchars($csv[$i][1])."</div>\n";
  echo "<div class='body'>".nl2br(htmlspecialchars($csv[$i][2]))."</div>\n";
  echo "<hr class='kugiri' />\n";
}
?>
</div>
</body>
</html>

簡易掲示板 PHP4版

<?php
/***********************************************************
**    PHPマスター bbs.php  Version 01 for PHP4
**    Copyright(c) 2010 Inter Space Planning.
**    http://blog.info-square.jp/scriptmaster/
*************************************************************/
setlocale(LC_ALL,"ja_JP.UTF-8");
require_once("fputcsv_php4.php");
//
$title   = "簡易掲示板";
$datadir = "./data/";
$myfile  = $datadir."data.txt";
//
$reload  = $_SERVER["SCRIPT_NAME"];
$act = $_POST['act'];
$nam = $_POST['b_name'];
$bod = $_POST['b_body'];
if($act) {
  if(!$nam) { $errormess["name"] = "名前が未入力です"; }
  if(!$bod) { $errormess["body"] = "本文を書いて下さい"; }
  if(!isset($errormess)) {
    $today = date("Y/m/d H:i:s");
    $newdata = array($today,$nam,$bod);
    $csvr[] = $newdata;
    $fp = fopen($myfile,"r");
    while($csvr[] = fgetcsv($fp,"1024")) {;}
    fclose($fp);
    array_pop($csvr);
    $fp = fopen($myfile,"w");
    foreach($csvr as $line) {
      fputcsv($fp,$line);
    }
    fclose($fp);
    header("Location: $reload");
  }
}
?>
<!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" />
<link rel="stylesheet" href="style.css" />
<title><?php echo $title; ?></title>
</head>
<body>
<div id="bbsform">
<h1><?php echo $title ?></h1>
<form action="<?php echo $reload ?>" method="post">
<input type="hidden" name="act" value="regist">
お名前:
<input type="text" name="b_name" size="30" value="<?php echo $nam; ?>" /><br />
<textarea name="b_body" rows="10" cols="50"><?php echo $bod; ?></textarea><br />
<input type="submit" value="登録" class="mybutton" />
<input type="reset" value="書き直し" />
<input type="button" value="再読込" onClick="location.href='<?php echo $reload; ?>'" />
</form>
<?php
if(isset($errormess)) {
  echo "<ul class='err'>\n";
  foreach ($errormess as $key => $val) { echo "<li>".$val."</li>\n"; }
  echo "</ul>\n";
}
?>
</div>
<div id="bbslog">
<?php
$fp = fopen($myfile,"r");
while($csv[] = fgetcsv($fp,"1024")) {;}
fclose($fp);
array_pop($csv);
for($i=0; $i<count($csv); $i++) {
  echo "<div class='date'>".$csv[$i][0]."</div>\n";
  echo "<div class='name'>".htmlspecialchars($csv[$i][1])."</div>\n";
  echo "<div class='body'>".nl2br(htmlspecialchars($csv[$i][2]))."</div>\n";
  echo "<hr class='kugiri' />\n";
}
?>
</div>
</body>
</html>

PHPマスター関連記事