掲示板を作成

トップページ

  • 掲示板へのリンクを作る


《index.php

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テニスサークル交流サイト</title>
</head>
<body>
<h1>テニスサークル交流サイト</h1>
<p><a href="album.php">アルバム</a></p>
<p><a href="bbs.php">掲示板</a></p>
<h2>お知らせ</h2>
</body>
</html>

入力フォームの作成

《bbs.php

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>交流サイト:掲示板</title>
</head>
<body>
<h1>掲示板</h1>
<form action="write.php" method="post">
<p>名前:<input type="text" name="name"></p>
<p>タイトル:<input type="text" name="title"></p>
<textarea name="body"></textarea>
<p>削除パスワード(数字4桁):<input type="text" name="pass"></p>
<p><input type="submit" value="書き込む"></p>
</form>
<p><a href="index.php">トップページに戻る</a></p>
</body>
</html>


データベース書き込みプログラム

  • bbs.phpで入力されたデータを受信し、入力項目のうちの必須項目(名前、本文)がきちんと記入されているか調べます
  • 入力漏れがなければデータベースに接続し、テーブルにレコードを追加します
  • この場合、エラー時にbbs.phpに戻すではわかりにくいので、index.phpに戻す設定にしています


《write.php

<?php
  // データの受け取り
  $name = $_POST['name'];
  $title = $_POST['title'];
  $body = $_POST['body'];
  $pass = $_POST['pass'];

  // 必須項目チェック(名前か本文が空ではないか?)
  if ($name == '' || $body == ''){
    header('Location: index.php'); // index.phpへ移動
    exit(); // 終了
  }
  // 必須項目チェック(パスワードは4桁の数字か?)
  if (!preg_match("/^[0-9]{4}$/", $pass)){
    header('Location: index.php');
    exit();
  }

  // データベースに接続
  $dsn = 'mysql:host=localhost;dbname=tennis;charset=utf8';
  $user = 'tennisuser';
  $password = 'xxxxxxxx'; // tennisuserに設定したパスワード

  try {
    $db = new PDO($dsn, $user, $password);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
    // プリペアドステートメントを作成
    $stmt = $db->prepare("
      INSERT INTO bbs (name, title, body, date, pass)
      VALUES (:name, :title, :body, now(), :pass)"
    );
    // パラメータを割り当て
    $stmt->bindParam(':name', $name, PDO::PARAM_STR);
    $stmt->bindParam(':title', $title, PDO::PARAM_STR);
    $stmt->bindParam(':body', $body, PDO::PARAM_STR);
    $stmt->bindParam(':pass', $pass, PDO::PARAM_STR);
    // クエリの実行
    $stmt->execute();

    // index.phpに戻る
    header('Location: index.php');
    exit();
  } catch(PDOException $e) {
    die ('エラー:' . $e->getMessage());
  }
  • 投稿後のデータベースの表示


必須項目のチェック

POSTメソッドでデータを受け取る
<?php
  // データの受け取り
  $name = $_POST['name'];
  $title = $_POST['title'];
  $body = $_POST['body'];
  $pass = $_POST['pass'];
名前と本文のチェック
  • 必須項目のチェック
  • isset() あるかどうか
  • empty() 無いかどうか


指定したURLへジャンプする

header ( 'Location: 戻り先のURL' );
  • headerは、HTTPヘッダを送信するための関数
  • 他のページへのジャンプを指示する情報
  • 「bbs.php」に戻す
削除パスワードの桁数チェック
  • 削除パスワードが数字4桁であるかどうかを確認し、4桁でなければ必須項目チェックと同様に「bbs.php」に戻す処理です


正規表現

  • preg_match は、第1引数に指定したパターンに、第2引数に指定した文字が合っていれば true を返すので、false のときは bbs.php に戻るようにします
preg_match ( "/^[0-9]{4}$/", $pass )

^    先頭
[0-9]  0から9の数字
{4}   4桁
$   末尾

  • $passは、「1234」はマッチするので true、「aaaa」はマッチしないので false

サーバーとデータベースの指定

  • データベースに接続するときに必要な DSN とユーザー名、パスワードです
<?php
  // データベースに接続
  $dsn = 'mysql:host=localhost; dbname=tennis; charset=utf8';
  $user = 'tennisuser';
  $password = 'password'; // tennisuserに設定したパスワード


DSN(Data Source Name)

  • DSNとは、どのサーバーにあるどんなデータベースを使うのかを指定した文字列のこと
mysql: host=ホスト名; dbname=データベース名; charset=文字コード
  • write.php では、ホスト名は localhost、データベース名は tennisです
  • ここで tennis データベースを選択しているので、USE文を実行したのと同じ効果があります

例外処理

  • 「try-catch」は、例外処理のための構文です
  • 「try-catch」で例外の処理をしなかったら、例外が発生した段階でプログラムが止まってしまい、期待通りにその後の処理が実行されません
  • このプログラムの場合、PDOException という種類の例外が発生したときのみ、catchの中の処理が実行されます
<?php
try {
    $db = new PDO($dsn, $user, $password);
      (略)
  } catch(PDOException $e) {
    die ('エラー:' . $e->getMessage());
  }
  1. 例外が発生しそうな処理を「try」の中に入れておく
  2. 例外が発生すると Exception を投げる(Throw する)
  3. 例外を catch すると、catch 内の処理を実行する

PDO(PHP Data Objects)

  • PDOとは、さまざまなデータベースを簡単に利用できるようにする、PHP拡張機能です
  • PHPDBMSの間に「抽象化レイヤー」を挟んで各種DBMSの違いをこのレイヤーで吸収し、異なるDBMS に対して同じプログラムで同じ処理をできるようにする
  • 抽象化レイヤーには、PDO(PHPプログラムで使うデータベース接続の機能)と、PDOが使う各種DBMS用ドライバ(DBMSとPDOをつなぐ機能)が含まれています
  • しかし、ドライバを意識する必要はない
$db = new PDO($dsn, $user, $password);

オブジェクト指向

  • オブジェクト指向では、プログラムが再利用しやすいように、「クラス」という処理の設計図から「インスタンス」と呼ばれる実体を作成します
  • この作成した実体のことを「オブジェクト」と呼びます
  1. クラスをもとにインスタンスを作成
  2. インスタンスにはメソッドという関数のような処理群がある
  3. クラスを継承して機能拡張も簡単
$db = new PDO($dsn, $user, $password);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

プリペアドステートメント(テンプレート)

  • プリペアドステートメントは、PDOインスタンスのメソッドを実行するための構文
  • PDOのインスタンスである $db が持っている、prepare というメソッドを実行します
  • メソッドは、オブジェクトが持つ関数のようなもので、アロー演算子(->)で「このオブジェクトのこの関数を使う」ということを明示的に表します
  • プリペアドステートメントとは、実行したいクエリのテンプレートのようなものです
  • 「:名前」の部分に、bindParamメソッドで後から値を埋め込みます
  • 後から値を埋め込む「:〜」の部分のことをプレースホルダーと呼びます
$db->prepare( "ステートメント文字列" );
$stmt = $db->prepare("
  INSERT INTO bbs (name, title, body, date, pass)
  VALUES (:name, :title, :body, now(), :pass)"
);
PDOStatement::bindParam

INSERT 文によるレコード追加

  • INSERT 文は、テーブルに新しいレコードを追加するSQLの構文です
  • nameやtitleのように文字列を値としたときに、通常クォーテーションで文字列を囲む必要がありますが、プリペアドステートメント使う場合は、自動的にクォーテーションをつけてくれるため不要です
  • dateは、日付時刻を指定するカラムですが、now() を指定しておくとレコード追加時に自動で日付時刻に展開してくれます
  • now() は、MySQLの持つ現在日時を表す関数を呼び出しています
INSERT INTO テーブル名 (カラム1, カラム2, カラム3, ・・・)
VALUES (値1, 値2, 値3, ・・・)"
executeメソッド
  • クエリの実行
$stmt->execute();
  • クエリが終わったら、header関数を使って「bbs.php」へ戻す
header('Location: bbs.php');



個々までの例は、セキュリティ対策を簡略化しています。
外部に公開するには、セキュリティ対策が必須になります。