データベース名のbbs 、そのbbsテーブルからデータを読み込んで表示するよう、bbs.phpファイルを修正します。ページの冒頭部分と本文部分を修正していきます。
bbs.php
ここから冒頭部分 | |
<?php $num = 10; | 1ページに表示される書き込みの件数を10件として、変数numに代入 |
$dsn = ‘mysql:host=localhost;dbname=baseball;charset=utf8’; $user = ‘baseballuser’; $password = ‘ ここにはパスワードを’; | データベースへ接続する際の設定。この部分では、DSNとユーザー名、パスワードを設定しています。DSNとはData Source Nameの略。どのサーバーのどのデータベースを使うのか指定します。 書式は「mysql:host=ホスト名;dbname=DB名;charset=文字コード」 |
$page = 1; if(isset($_GET[‘page’] && $_GET[‘page’] > 1){ $page = intval($_GET[‘page’]); }) | ページを指定する処理。 指定がない場合は1ページ目で、GETメソッドで1より大きなページ数が指定されてれば、指定のコメントを表示する処理。 |
try { $db = new PDO($dsn ,$user, $password ); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); | PDO(php Data Object)とはDBMS(DB管理システム)を簡単に利用できるようにするPHP拡張機能。 PDOは様々な異なるDBMS(例えばOracleやSQLiteなど)に対して同じ処理ができるようにします。 new演算子を使ってPDOクラスのインスタンスを作成します。その時引数にDSN、ユーザー名、パスワードを必要とし変数dbに代入。 アロー関数(->)によりsetAttributeメソッドを使い、プリペアードステートメントを使う際に、セキュリティを高めるための設定をしてます。 |
$stmt = $db->prepare(“SELECT * FROM bbs ORDER BY date DESC LIMIT :page, :num”); | プリペアードステートメント作成。 プリペアードステートメントとは、実行したいクエリのテンプレートのようなものです。 それぞれの意味は次の通りです。「SELECT」(取得する)、「*」(全部)、「FROM bbs」(bbsから)「 ORDER BY 」(並び順)「date DESC」(dateの降順)「 LIMIT」(件数)「 :page, :num」(page件目からnum件) |
$page = ($page-1) * $num; $stmt->bindparam(‘:page’, $page, PDO::PARAM_INT); $stmt->bindparam(‘:num’, $num, PDO::PARAM_INT); | bindparamメソッドで値を割り当てます。数字の割り当てにはPDO::PARAM_INTという定数を使います。 1ページ目なら0件目から、2ページ目なら10件目から取得したいので:pageにはGETメソッドで指定されたページ数から1引いた数に、1ページの表示件数をかけたものを指定します。 |
$stmt->execute(); } catch (PDOException $e){ exit(‘エラー:’ . $e->getMessage()); } ?> <!DOCTYPE html> <html lang=”ja”> ~ | クエリを実行しているのはexecute()です。プリペアードステートメントでクエリを組み立ててexecute()で実行します。 catch (PDOException $e){~ではPDOExceptionという種類の例外が発生したときのみ、catch内の処理を実行します。PDOExceptionは$eという変数に代入され、$e->getMessage()でエラーメッセージが取得できます。exitに引数としてエラーメッセージを指定すると、それを表示してプログラムを終了することができます。 |
<!– ここから本文 –> | |
<?php while ($row = $stmt->fetch()): ?> | レコードの取得。 while構文で1レコードずつ取り出していきます。HTMLを多く含むので、while構文の別の書き方(while~endwhile)を使っています。結果セット(取得してくるレコード群)からレコードが取得できている間はカッコ内の式の評価がTRUEになり、レコードを取得し終えたときにwhile構文を抜けます。レコードを取得するには$stmtのfetchメソッドを利用します。 |
<div class=”card”> <div class=”card-header”> <?php echo $row[‘title’]? $row[‘title’]: ‘(無題)’ ?> </div> <div class=”card-body”> <p class=”card-text”><?php echo nl2br($row[‘body’]) ?></p> </div> <div class=”card-footer”> <form action=”delete.php” method=”post” class=”form-inline”> <?php echo $row[‘name’] ?> (<?php echo $row[‘date’] ?>) <input type=”hidden” name=”id” value=”<?php echo $row[‘id’] ?>”> <input type=”text” name=”pass” placeholder=”削除パスワード” class=”form-control”> <input type=”submit” value=”削除” class=”btn btn-dark”> </form> </div> </div> <hr> <!–水平線を引くタグ –> <?php endwhile; ?> | タイトルがないまま投稿された場合は(無題)と表示しますが、ここでは三項演算子を使用してます。 「条件式? 式1 : 式2」条件式の結果がTRUEなら式1を、FALSEなら式2を返します。$row[‘title’]にタイトルがあれば式1としてそのままタイトルを表示、なければ式2として無題と表示。 <div class=”card-footer”> 「コメント削除フォーム」 書き込みを削除するdelete.phpファイルは後で作成します typeがhiddenのテキストボックスは、画面に現れない非表示の入力欄です。非表示ですがnameやvalueなどの属性を持たせることができます。削除パスワードと一緒に書き込みのidを送信して、削除したい書き込みを指定します。 |
<?php try { $stmt = $db->prepare(“SELECT COUNT(*) FROM bbs”); $stmt->execute(); } catch (PDOException $e){ exit(‘エラー:’ . $e->getMessage()); } | 「ページ数の表示」 「プリペアードステートメントの作成」 SELECTはデータを取得するときの命令です。COUNT関数はカッコ内に指定したカラムのうち、値がNULLでないものの行数を数えます。ここではbbsテーブルにあるすべての書き込みの数を調べるので、特定のカラム(列)ではなく「*」ですべてを指定します。 |
$comments = $stmt->fetchColumn(); $max_page = ceil($comments / $num); if($max_page >= 1){ echo ‘<nav><ul class=”pagination”>’; for ($i =1; $i <= $max_page; $i++){ echo'<li class=”page-item”>a href=”bbs.php?page=’.$i.'”>’.$i.'</a></li>’; } echo ‘</ul></nav>’; } ?> | fetchColumn()メソッドの引数を指定しなかった場合、最初のカラムの内容を取得します。今回のクエリで取得してくるのはbbsテーブルの行数です。 ページ数を算出するには、書き込み全件数を表示件数である10件で割り、結果を端数切り上げすます。例えば25件のコメントを10件ずつ表示すると、結果は2.5のため、端数を切り上げて3ページになります。切り上げはceil関数で行います。 端数切り上げの結果、1ページ以上表示する場合は、1ページ目から$max_pageまでページリンクを表示します。 |
delete.php
<?php $id = intval($_POST[‘id’]); $pass = $_pass[‘pass’]; | データーの受け取り |
if($id == ” || $pass == ”){ header(‘Location: bbs.php’); exit(); } | 必須項目のチェック |
$dsn = ‘mysql:host=localhost;dbname=baseball;charset=utf8’; $user = ‘baseballuser’; $password = ‘0529’; try { // PDOインスタンスの生成 $db = new PDO($dsn, $user, $password); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); | データベースに接続 |
$stmt = $db->prepare(“DELETE FROM bbs WHERE id=:id AND pass=:pass “); | プリペアドステートメントを作成。 削除のクエリにはDELETE文を使用します。 FROMで指定したテーブルから、WHERE句の条件に合うレコードを削除します。 ANDでどちらも一致することが条件にしています。WHERE句の条件がないとすべてのレコードが削除されてしまいますので注意。 |
$stmt->execute(); } catch (PDOException $e){ exit(“エラー:” . $e->getMessage()); } header(‘Location: bbs.php’); exit(); ?> | クエリの実行 |