PHP & MySQL 陽春留言板實作


Posted by chihyu on 2021-01-25

實作流程

1. 確認要做的產品 -- 留言板

2. 規劃產品路由、功能 (有甚麼檔案、要做甚麼事)

初階陽春版
index.php 顯示所有流言
handle_add_comment.php 處理新增留言邏輯

3. 規劃資料結構、建立資料庫

資料表: Comments
欄位:id、nickname、content、created_at

4. 實作前端頁面

搜尋 html starter,放入 index.php,修改 head 的內容

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>留言板</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="./style.css">
</head>
<body>
</body>
</html>

把靜態內容完成,並設定 CSS

5. 串接資料庫

新增檔案 index.php,在 index.php 裡面引入資料庫,撈出資料

<?php
  require_once('conn.php');

  $result = $conn->query("SELECT * FROM comments ORDER BY id DESC");
  if (!$result) {
    die('Error:' . $conn->error);
  }
?>

6. 顯示資料

<body> 裡面插進 php,用 php 把資料顯示出來(html 可以跟 php 混著寫)

...
<section>
  <?php
    while($row = $result->fetch_assoc()) {
  ?>
      <div class="card">
          <div class="card_avatar"></div>
          <div class="card_body">
            <div class="card_info">
              <span class="card_author"><?php echo $row['nickname'] ?></span>
              <span class="card_time"><?php echo $row['created_at'] ?></span>
              <div class="card_content"><?php echo $row['content'] ?></div>
            </div>
          </div>
        </div>
  <?php } ?>
</section>
...

7. 擴充:新增留言功能

新增檔案 handle_add_comment.php -> 引入資料庫 -> 檢查 POST 是否為空(帶入參數,讓錯誤訊息顯示在首頁) -> 執行新增資料的 sql

<?php 
  require_once('./conn.php');

  if (empty($_POST['nickname'] || $_POST['content'])) {
    header('Location: ./index.php?errCode=1');
    die('empty data');
  }

  $nickname = $_POST['nickname'];
  $content = $_POST['content']

  $sql = sprintf(
    "INSERT INTO comments(nickname, content) 
      VALUES ('%s', '%s')",
    $nickname,
    $content
  );
  $result = $conn->query($sql);
  if ($result) {
    header('Location: ./index.php');
  } else {
    die('failed:' . $conn->error);
  }
 ?>

index.php 首頁錯誤訊息顯示

<?php 
  if (!empty($_GET['errCode'])) {
    $code = $_GET['errCode'];
    $msg = 'Error';
    if ($code === '1') {
      $msg = '資料不齊全';
    }
    echo '<h3 class="error">' . $msg . '</h3>';
  }
?>

整個陽春留言板大致上的流程:

  1. 確認產品 (主體)
  2. 規劃路由、功能 (在甚麼檔案要做甚麼事)
  3. 規劃資料結構、建立資料庫 (決定動態內容有哪些)
  4. 實作前端頁面 (畫面切版)
  5. 串接資料庫 (引入動態內容)
  6. 顯示資料內容
  7. 建立其他功能的檔案 (擴充功能)

8. 擴充:會員註冊、登入、登出功能(重複以上流程)

a. 規劃路由、功能:

register.php 註冊頁面
handle_registet.php 處理註冊邏輯
login.php 登入頁面
handle_login.php 處理登入邏輯
handle_logout.php 處理登出邏輯

b. 規劃資料結構、建立資料庫:

資料表: users
欄位:id、nickname、username(設為 unique)、password、created_at

c. 實作前端頁面(頁面連結按鈕、註冊頁面、登入頁面):

index.php 新增按鈕
<a class="change_page_btn" href="./register.php">註冊</a>
<a class="change_page_btn" href="./login.php">登入</a>
<a class="change_page_btn" href="./logout.php">登出</a>
register.php 註冊頁面

直接複製 index.php 來修改,把不要的刪掉,把 form 裡面的內容改掉,action 連到處理註冊邏輯的檔案

<form class="board_new_comment" method="POST" action="./handle_register.php">
  <div class="nickname">
    <span>暱稱:</span>
    <input type="text" name="nickname" />
  </div>
  <div class="nickname">
    <span>帳號:</span>
    <input type="text" name="username" />
  </div>
  <div class="nickname">
    <span>密碼:</span>
    <input type="password" name="password" />
  </div>
  <input class="register_submit_btn" type="submit" />
</form>
login.php 登入頁面

直接複製 register.php 來修改,action 連到處理註冊登入邏輯的檔案

<form class="board_new_comment" method="POST" action="./handle_login.php">
  <div class="nickname">
    <span>帳號:</span>
    <input type="text" name="username" />
  </div>
  <div class="nickname">
    <span>密碼:</span>
    <input type="password" name="password" />
  </div>
  <input class="login_submit_btn" type="submit" />
</form>

d. 建立處理功能邏輯的檔案(註冊功能、登入功能)

handle_register.php 註冊功能

複製 handle_add_comment.php 來改

$nickname = $_POST['nickname'];
$username = $_POST['username'];
$password = $_POST['password'];

if (empty($nickname) || empty($username) || empty($password)) {
header('Location: ./register.php?errCode=1');
die('empty data');
}

$sql =  sprintf(
    "INSERT INTO comments(nickname, username, password ) 
      VALUES ('%s', '%s', '%s')",
    $nickname,
    $username, 
    $password
  );

查看 errno 來驗證 username 是否已被註冊

$code = $conn->errno;// error 的 number
if ($code === 1062) {//duplicate entry 雙重輸入 的 errno 是 1062
  header('Location: ./register.php?errCode=2');
}
handle_login.php 登入頁面

查看 users 資料表是否有輸入的帳號密碼

if (empty($username) || empty($password)) {
    header('Location: ./login.php?errCode=1');
    die('empty data');
  }

  // 從資料庫找到包含 username 跟 password 的資料
  $sql = "SELECT * FROM users WHERE username = '$username' and password ='$password'";
  $result = $conn->query($sql);
  if (!$result) {
    die($conn->error);
  }

  // 如果有找到資料 num_rows=1
  if ($result->num_rows) {
    header('Location: ./index.php');
  } else {
    header('Location: ./login.php?errCode=2');
  }

後續留言板問題修正參考:PHP 留言板問題修正


#Web #MySQL #PHP #Message board







Related Posts

[練習] CSS: Loaders

[練習] CSS: Loaders

上線個人頁面到Netlify+啟動Netlify CMS

上線個人頁面到Netlify+啟動Netlify CMS

筆記、[ALG101] 看懂題目+寫程式

筆記、[ALG101] 看懂題目+寫程式


Comments