PHPの学習の為、掲示板のサイトを作成致しました。
掲示板は、投稿されたコメント一覧及び、書き込みフォームを表示する「bbs_1.php」書き込みフォームより投稿されたコメントを処理する「write1.php」コメント一覧部分の削除フォームから、削除パスワードを入力された場合にコメントを削除する、「delete1.php」の3つのファイルで構成しております。ですが、学習の為、関数切り分けを行いたいと思い、データベース接続部分のPDOインスタンスを作成する部分「Db_connect.php」、及び、データベースの接続情報を定数として、定義した、「config.php」作成し、処理を切り分けてみました。
php
1<?php 2 3require_once 'Db_connect.php'; 4require_once 'config.php'; 5 6 error_reporting(E_ALL); 7 ini_set("display_errors",1); 8 9 //1ページに表示されるコメントの数 10 $num = 10; 11 //ページ数が指定されている時 12 $page = 0; 13 if(isset($_GET['page']) && $_GET['page'] > 0){ 14 $page = intval($_GET['page']) -1; 15 } 16 17 try{ 18 19 $dbh = db_connect(DSN,DB_USERNAME,DB_PASSWORD); 20 $stmt = $dbh->prepare("SELECT id,name,title,comment,created_at,password FROM post ORDER BY created_at DESC LIMIT 21 :page,:num"); 22 //パラメーターを割り当て 23 $page = $page * $num; 24 25 $stmt->bindValue(':page',$page,PDO::PARAM_INT); 26 $stmt->bindValue(':num',$num,PDO::PARAM_INT); 27 $stmt->execute(); 28 }catch(PDOException $e){ 29 echo "エラー: " . $e->getMessage(); 30 } 31 32?> 33 34 <html> 35 <head> 36 <title>交流サイト:掲示板</title> 37 <meta charset="utf-8"> 38 </head> 39 <body> 40 <h1>掲示板</h1> 41 <form action="write1.php" method="post"> 42 <p>名前:<input type="text" name="name" value="<?php echo isset($_COOKIE['name']) ? $_COOKIE['name'] : '' ?>"></p> 43 <p>タイトル:<input type="text" name="title" size="60"></p> 44 <textarea name="comment"></textarea> 45 <p>削除パスワード(数字4桁):<input type="text" name="pass"> 46 <input type="submit" name="submit" value="書き込む"> 47 <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>"> 48 </form> 49 <hr> 50 <?php 51 while($row = $stmt->fetch()): 52 53 $title = $row['title'] ? $row['title'] : '(無題)'; 54 ?> 55 <p>名前:<?php echo $row['name'] ?></p> 56 <p>タイトル:<?php echo $title ?></p> 57 <p><?php echo nl2br(htmlspecialchars($row['comment'],ENT_QUOTES,'UTF-8'),false) ?></p> 58 <p><?php echo $row['created_at'] ?></p> 59 <form action="delete1.php" method="post"> 60 <input type="hidden" name="id" value="<?php echo $row['id']; ?>"> 61 削除パスワード:<input type="password" name="pass"> 62 <input type="submit" value="削除"> 63 <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>"> 64 </form> 65 <?php 66 endwhile; 67 //ページ数の表示 68 try{ 69 $stmt = $dbh->prepare("SELECT COUNT(*) FROM post"); 70 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 71 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 72 73 //クエリの実行 74 $stmt->execute(); 75 76 }catch(PDOException $e){ 77 echo "エラー:" . $e->getMessage(); 78 } 79 /** 80 * コメントの件数を取得 81 *fetchColumn関数で 最初のレコードを取り出し、最初の列「id」のデータを取り出す 82 * idは降順に設定されているため、コメントの件数が分かる 83 * */ 84 $comments = $stmt->fetchColumn(); 85 $max_page = ceil($comments / $num); 86 echo '<p>'; 87 for($i = 1; $i <= $max_page; $i++){ 88 echo '<a href="bbs.php?page=' . $i .'">' . $i . 89 '</a> '; 90 } 91 echo '</p>'; 92 ?> 93 94 </body> 95 </html>
上記は、「bbs_1.php」になります。
php
1<?php 2 3require_once 'Db_connect.php'; 4require_once 'config.php'; 5 6error_reporting(E_ALL); 7ini_set('display_errors', '1'); 8 9$err_message = []; 10 11if(!empty($_POST)){ 12 13 $title = filter_input(INPUT_POST,'title',FILTER_SANITIZE_SPECIAL_CHARS); 14 $token = filter_input(INPUT_POST,'token',FILTER_SANITIZE_SPECIAL_CHARS); 15 16 if(!$name = filter_input(INPUT_POST,'name',FILTER_SANITIZE_SPECIAL_CHARS)){ 17 $err_message[] = '名前が入力されていません'; 18 } 19 20 if(!$pass = filter_input(INPUT_POST,'pass',FILTER_SANITIZE_SPECIAL_CHARS)){ 21 $err_message[] = 'パスワードが入力されていません'; 22 } 23 24 if(!$comment = filter_input(INPUT_POST,'comment',FILTER_SANITIZE_SPECIAL_CHARS)){ 25 $err_message[] = 'コメントが入力されていません'; 26 } 27 28} 29 30 31if(!preg_match("/^[0-9]{4}$/",$pass)){ 32 33 $err_message[] = 'パスワードを4文字で入力してください'; 34 35} 36 37$pass = password_hash($pass,PASSWORD_DEFAULT); 38 39if(count($err_message) === 0){ 40 //CSRF対策 41 if(!password_verify(session_id(),$token)){ 42 header('Location:bbs_1.php'); 43 exit(); 44 } 45 46 setcookie('name',$name,time() + 60 * 60 * 24 * 30); 47 48 49 50 //データベースに接続 51 52 53 try{ 54 55 $dbh = db_connect(DSN,DB_USERNAME,DB_PASSWORD); 56 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 57 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 58 $stmt = $dbh->prepare(" 59 INSERT INTO post (name,title,comment,created_at,password) 60 VALUES (:name, :title, :comment, now(), :pass)"); 61 $stmt->bindValue(':name',$name,PDO::PARAM_STR); 62 $stmt->bindValue(':title',$title,PDO::PARAM_STR); 63 $stmt->bindValue(':comment',$comment,PDO::PARAM_STR); 64 $stmt->bindValue(':pass',$pass,PDO::PARAM_STR); 65 $stmt->execute(); 66 67 }catch(PDOException $e){ 68 die ('エラー:' . $e->getMessage()); 69 } 70 71} 72 73?> 74<html> 75<head> 76 <meta charset="utf-8"> 77 <title>Page Title</title> 78 79</head> 80<body> 81 <?php 82 echo implode("<br />",$err_message); 83 ?> 84 <h4>投稿に成功しました。</h4> 85 <p><a href="bbs.php">戻る</a> 86 87</body> 88</html> 89
上記は「write1.php」になります。
php
1<?php 2 require_once 'config.php'; 3 require_once 'Db_connect.php'; 4 error_reporting(E_ALL); 5 ini_set("display_errors",1); 6 7 //エラーメッセージ 8 $err_msg = []; 9 10 if(!empty($_POST)){ 11 12 if(!$pass = filter_input(INPUT_POST,'pass',FILTER_SANITIZE_SPECIAL_CHARS)){ 13 14 $err_msg[] = 'パスワードが入力されていません。'; 15 16 } 17 18 19 $token = filter_input(INPUT_POST,'token',FILTER_SANITIZE_SPECIAL_CHARS); 20 21 //POSTされたIDを取得 22 $id = filter_input(INPUT_POST,'id',FILTER_SANITIZE_SPECIAL_CHARS); 23 $id = intval($id); 24 25 } 26 27 //CRLF対策 28 if(!password_verify(session_id(),$token)){ 29 header('Location:bbs.php'); 30 exit(); 31 }; 32 33 if(count($err_msg) === 0){ 34 35 36 try{ 37 $dbh = db_connect(DSN,DB_USERNAME,DB_PASSWORD); 38 $stmt = $dbh->prepare(" 39 SELECT password FROM post where id = :id 40 "); 41 42 $stmt->bindValue(':id',$id,PDO::PARAM_INT); 43 44 $stmt->execute(); 45 46 $db_pass = $stmt->fetch(); 47 48 if(!password_verify($pass,$db_pass['password'])){ 49 50 die('パスワードが違います'); 51 } 52 53 $stmt = $dbh->prepare(" 54 DELETE FROM post WHERE id = :id 55 "); 56 57 $stmt->bindValue(':id',$id,PDO::PARAM_INT); 58 $stmt->execute(); 59 60 }catch(PDOException $e){ 61 62 die( "エラー:" . $e->getMessage()); 63 } 64 65 header('Location: bbs_1.php'); 66 exit(); 67 68 } 69 70?>
上記は「delete1.php」になります。
php
1<?php 2define('DSN','mysql:host=localhost;dbname=online_bbs;charset=utf8'); 3define('DB_USERNAME', 'root'); 4define('DB_PASSWORD', '12345');
上記は「config.php」になります。
php
1<?php 2function db_connect($dsn,$user,$password){ 3 $dbh = new PDO($dsn,$user,$password); 4 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 5 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 6 return $dbh; 7}
上記は、「Db_connect.php」になります。
「bbs_1.php」「write1.php」「delete1.php」内で、他に関数切り分けした方が良いと思う箇所などがありましたら、ご助言頂きたいです。
よろしくお願いいたします。
回答5件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/04/01 08:05
2019/04/02 03:23
2019/04/02 03:31
2019/04/02 03:37
2019/04/02 03:37
2019/04/02 03:39
2019/04/02 03:46
2019/04/02 03:53
2019/04/02 03:57
2019/04/02 04:02 編集
2019/04/02 04:06
2019/04/02 04:08
2019/04/02 04:19
2019/04/02 04:20
2019/04/02 04:21
2019/04/02 04:33 編集
2019/04/02 04:38
2019/04/02 04:39
2019/04/02 04:46
2019/04/02 04:56
2019/04/02 06:15
2019/04/02 08:09
2019/04/02 08:16
2019/04/02 08:27
2019/04/02 08:45
2019/04/02 12:02
2019/04/02 12:09
2019/04/02 13:11
2019/04/02 13:15
2019/04/02 13:19 編集
2019/04/02 13:18
2019/04/02 13:29
2019/04/02 13:31
2019/04/02 13:38
2019/04/02 14:02 編集
2019/04/03 01:53 編集
2019/04/03 01:41
2019/04/03 05:15
2019/04/03 05:18
2019/04/03 05:41
2019/04/03 09:12 編集
2019/04/03 10:11
2019/04/03 10:31 編集
2019/04/03 10:29
2019/04/03 10:59
2019/04/04 00:55 編集
2019/04/03 12:08
2019/04/03 12:41
2019/04/03 12:45
2019/04/03 12:46
2019/04/03 12:50
2019/04/03 12:53
2019/04/03 12:54
2019/04/03 12:59
2019/04/03 13:06
2019/04/03 13:08 編集
2019/04/03 13:15
2019/04/03 13:20
2019/04/03 13:23
2019/04/03 13:35
2019/04/03 13:58
2019/04/03 14:02 編集
2019/04/03 14:26
2019/04/03 14:56 編集
2019/04/03 14:48
2019/04/03 15:04
2019/04/03 21:04 編集
2019/04/03 23:45
2019/04/04 00:05
2019/04/04 00:31
2019/04/04 00:45 編集
2019/04/04 00:56
2019/04/04 01:42
2019/04/04 02:30
2019/04/04 02:41
2019/04/04 04:25
2019/04/04 04:33