(17) SQLiteで簡易掲示板作成

投稿者: | 2016年11月14日

この記事は最終更新から 420日 が経過しています。

1. やりたいこと

まずは「投稿」、「編集」、「削除」を実装する。
画面レイアウトは index.php に書くように切り離してあるので、デザインきれい化は後で…

実行サンプルはこちらです。
http://www.dogrow.net/php/sample/00017/

2. プログラム作成

1) index.php

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SQLiteサンプル</title>
</head>
</body>
<?php
  require_once("CBbsMng.php");
  $cBbsMng = new CBbsMng();
  $cBbsMng->connect_db();

  // 投稿制御
  $cmd =(isset($_POST['cmd']))? $_POST['cmd'] : 0;
  if($cmd == 1){
    $tid   = htmlspecialchars($_POST['tid']);
    $title = htmlspecialchars($_POST['title']);
    $name  = htmlspecialchars($_POST['name']);
    $bun   = htmlspecialchars($_POST['bun']);
    if(($title == "") && ($name == "") && ($bun == "")){
      if($tid == 0){      // 新規スレッドを作成?
        $cBbsMng->create_thread($title, $name, $bun);
      }else{
        $cBbsMng->create_item($tid, $title, $name, $bun);
      }
    }
  }
  // スレッド表示
  $ary_th = $cBbsMng->get_thread();
  foreach($ary_th as $th){
    echo "<hr><h1 style=\"color:#f00\">".$th['title']."</h1>";
    $ary_it = $cBbsMng->get_item($th['tid']);
    foreach($ary_it as $it){
      echo "<h2>●".$it['title']." [".$it['name']."] ".strftime("%G/%m/%d %H:%M:%S",$it['dt_post'])."</h2>";
      echo "<p style=\"border:1px #000 solid;margin-left:2rem;padding:0.5rem;\">".$it['bun']."</p>";
    }
  }
?>

<hr>
<form enctype="multipart/form-data" action="./" method=post>
スレッド:<select name=tid>
<option value=0>新規作成</option>
<?
  foreach($ary_th as $th){
    echo "<option value=\"".$th['tid']."\">".$th['title']."</option>";
  }
?>
</select><br />
<input type=hidden name=cmd value=1>
タイトル:<input type=text name=title><br />
名前:<input type=text name=name><br />
記事:<textarea name=bun></textarea><br />
<input type=submit value="投稿">
</form>

</body>
</html>

2) CBbsMng.php

※threadと itemのテーブルを分ける必要はなかった… いつか一つにまとめよう。

<?php
class CBbsMng {
  private $m_db;        // SQLite3 instance
  private $m_db_fpath;  // DBファイルパス

  function __construct( $fpath = "thbbs.db" ) {
    $this->m_db = NULL;
    $this->m_db_fpath = $fpath;
  }

  // DB接続
  public function connect_db(){
    if($this->m_db == NULL){
      $isDbExist = file_exists($this->m_db_fpath);
      // DB接続
      $this->m_db = new SQLite3($this->m_db_fpath);
      $this->m_db->enableExceptions(TRUE);
      if($isDbExist === FALSE){   // DBは新規作成?
        try {
          // テーブルを作成
          $this->m_db->exec('begin');
          $this->m_db->exec("CREATE TABLE `thread` (`tid` INTEGER PRIMARY KEY, `top_iid` INTEGER, `new_iid` INTEGER, `dt_update` INTEGER);");
          $this->m_db->exec("CREATE TABLE `item`   (`iid` INTEGER PRIMARY KEY, `tid` INTEGER, `title` TEXT, `name` TEXT, `bun` TEXT, `dt_post` INTEGER);");
          $this->m_db->exec('commit');
        }catch(Exception $e){
          $this->m_db->exec('rollback');
          echo "[".__LINE__."] Caught exception: ".$e->getMessage();
        }
      }
    }
  }

  // スレッドを作成
  public function create_thread( $title, $name, $bun ){
    if($this->m_db != NULL){
      $dt_now = time();
      try {
        $this->m_db->exec('begin');
        // タイトルを作成
        $this->m_db->exec("INSERT INTO `thread` (`top_iid`,`new_iid`,`dt_update`) VALUES('0','0','0');");
        $tid = $this->m_db->lastInsertRowID();
        // 記事を作成
        $this->m_db->exec("INSERT INTO `item` (`tid`,`title`,`name`,`bun`,`dt_post`) VALUES('$tid','$title','$name','$bun','$dt_now');");
        $iid = $this->m_db->lastInsertRowID();
        // タイトルに先頭項目のIDを持たせる。
        $this->m_db->exec("UPDATE `thread` SET `top_iid`='$iid',`new_iid`='$iid',`dt_update`='$dt_now' WHERE `tid`='$tid';");
        $this->m_db->exec('commit');
      }catch(Exception $e){
        $this->m_db->exec('rollback');
        echo "[".__LINE__."] Caught exception: ".$e->getMessage();
      }
    }
  }

  // 記事を作成
  public function create_item( $tid, $title, $name, $bun ){
    if($this->m_db != NULL){
      $dt_now = time();
      try {
        $this->m_db->exec('begin');
        $this->m_db->exec("INSERT INTO `item` (`tid`,`title`,`name`,`bun`,`dt_post`) VALUES('$tid','$title','$name','$bun','$dt_now');");
        $iid = $this->m_db->lastInsertRowID();
        $this->m_db->exec("UPDATE `thread` SET `new_iid`='$iid',`dt_update`='$dt_now' WHERE `tid`='$tid';");
        $this->m_db->exec('commit');
      }catch(Exception $e){
        $this->m_db->exec('rollback');
        echo "[".__LINE__."] Caught exception: ".$e->getMessage();
      }
    }
  }

  // 記事を変更
  public function modify_item( $iid, $title, $name, $bun ){
    if($this->m_db != NULL){
      $dt_now = time();
      $rs = $this->m_db->query("SELECT `tid` FROM `item` WHERE `iid`='$iid';");
      $row = $rs->fetchArray();
      if(isset($row['tid']) === TRUE){
        try {
          $this->m_db->exec('begin');
          $tid = $row['tid'];
          $this->m_db->exec("UPDATE `item` SET `title`='$title',`name`='$name',`bun`='$bun',`dt_post`='$dt_now' WHERE `iid`='$iid';");
          $this->m_db->exec("UPDATE `thread` SET `new_iid`='$iid',`dt_update`='$dt_now' WHERE `tid`='$tid';");
          $this->m_db->exec('commit');
        }catch(Exception $e){
          $this->m_db->exec('rollback');
          echo "[".__LINE__."] Caught exception: ".$e->getMessage();
        }
      }
    }
  }

  // スレッドを削除
  public function delete_thread( $tid ){
    $ret = array();
    if($this->m_db != NULL){
      try {
        $this->m_db->exec('begin');
        // スレッドを削除
        $this->m_db->query("DELETE FROM `thread` WHERE `tid`='$tid';");
        // 配下の記事を削除
        $this->m_db->query("DELETE FROM `item` WHERE `tid`='$tid';");
        $this->m_db->exec('commit');
      }catch(Exception $e){
        $this->m_db->exec('rollback');
        echo "[".__LINE__."] Caught exception: ".$e->getMessage();
      }
    }
    return $ret;
  }

  // 記事を削除
  public function delete_item( $iid ){
    $ret = array();
    if($this->m_db != NULL){
      try {
        $this->m_db->exec('begin');
        $this->m_db->query("DELETE FROM `item` WHERE `iid`='$iid';");
        $this->m_db->exec('commit');
      }catch(Exception $e){
        $this->m_db->exec('rollback');
        echo "[".__LINE__."] Caught exception: ".$e->getMessage();
      }
    }
    return $ret;
  }

  // スレッドを取得
  public function get_thread(){
    $ret = array();
    if($this->m_db != NULL){
      try {
        // 全スレッド情報を取得
        $rs = $this->m_db->query("SELECT * FROM `thread` ORDER BY `dt_update` DESC;");
        while($row = $rs->fetchArray()){
          if(isset($row['tid']) === TRUE){
            // 1スレッドの先頭記事を取得
            $rs2 = $this->m_db->query("SELECT * FROM `item` WHERE `iid`='".$row['top_iid']."';");
            $row2 = $rs2->fetchArray();
            if(isset($row2['iid']) === TRUE){
              $row['title'] = $row2['title'];
              $ret[] = $row;
            }
          }
        }
      }catch(Exception $e){
        echo "[".__LINE__."] Caught exception: ".$e->getMessage();
      }
    }
    return $ret;
  }

  // 記事を取得
  public function get_item( $tid, $iid=-1 ){
    $ret = array();
    if($this->m_db != NULL){
      try {
        $where = "`tid`='$tid'";
        if($iid != -1){
          $where .= " `iid`='$iid'";
        }
        // 記事情報を取得
        $rs = $this->m_db->query("SELECT * FROM `item` WHERE $where ORDER BY `iid`;");
        while($row = $rs->fetchArray()){
          if(isset($row['iid']) === TRUE){
            $ret[] = $row;
          }
        }
      }catch(Exception $e){
        echo "[".__LINE__."] Caught exception: ".$e->getMessage();
      }
    }
    return $ret;
  }
}
?>

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)