用 PHP 與 MySQL 學習後端基礎(三)實作 API


Posted by ericcch24 on 2020-10-16

PHP 與 API 拿取資料的差異

PHP

  1. 把資料利用 SQL 指令拿出來
  2. 把資料 HTML 跟結合(UI)再一起
  3. 回傳 HTML

browser render: 留言板
==這時候是 server-side render,在伺服器端就把資料跟 HTML 綁好回傳,所以瀏覽器接收到的資料已經有介面,就可以直接顯示。==

API

  1. 把資料拿出來
  2. 變成某種格式(JSON),因為沒有與 HTML 結合所以不會有介面,只是資料
  3. 回傳

透過 JS render => 顯示資料
==資料回傳時 HTML 還是空的,因此瀏覽器在拿到後端資料還需要經過 JS render 來動態顯示資料。==

參考資料:跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR


用 PHP 實作 API:列出所有文章

  // 以上都與 index.php 相同
  // 將 SQL 抓的資料以陣列形式印出
  while($row = $result->fetch_assoc()) {
    array_push($comments, array(
      "id" => $row["id"], 
      "username" => $row["username"],
      "nickname" => $row["nickname"],
      "content" => $row["content"],
      "created_at" => $row["created_at"]
    ));
  }

  // 將陣列轉成 JSON 格式
  $json = array(
    "comments" => $comments
  );

  $response = json_encode($json);
  // 編碼讓瀏覽器可以讀取
  header('Content-type:application/json;charset=utf-8');
  echo $response;

用 PHP 實作 API:新增文章

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

  header('Content-type:application/json;charset=utf-8');

  if (empty($_POST['content'])) 
  {
    $json = array(
      "ok" => false,
      "message" => "Please input content"
    );

    $response = json_encode($json);
    echo $response;
    die();
  }

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


  $sql = "INSERT INTO ericcch24_comments(username, content) VALUES(?, ?)";
  $stmt = $conn->prepare($sql);
  $stmt->bind_param('ss', $username, $content);
  $result = $stmt->execute();
  if (!$result) {
    $json = array(
      "ok" => false,
      "message" => die($conn->error)
    );

    $response = json_encode($json);
    echo $response;
    die();
  }

  $json = array(
    "ok" => true, //新增成功時為 ok 狀態
    "message" => "Success"
  );

  $response = json_encode($json);
  echo $response;
?>

透過前端串接 API

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>留言板</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header class="warning">
    <strong>注意!本站為練習用網站,因教學用途刻意忽略資安的實作,註冊時請勿使用任何真實的帳號或密碼。</strong>
  </header>
  <main class="board">

    <h1 class="board__title">Comments</h1>


    <form class="board__new-comment-form">
      <textarea name="content" rows="5"></textarea>
      <input class="board__submit-btn" type="submit" />
    </form>
    <div class="board__hr"></div>
      <section>

      </section>
  </main>
</body>
<script>
  //用 ajax 取得資料後放到 html 上面
  let request = new XMLHttpRequest();
  request.open('GET', 'api_comments.php', true);

  request.onload = function() {
    if (this.status >= 200 && this.status < 400) {
      // Success!
      let resp = this.response;
      let json = JSON.parse(resp);
      let comments = json.comments;

      for (let i = 0; i < comments.length; i++) {
        let comment = comments[i];
        let div = document.createElement('div');
        div.classList.add('card');
        div.innerHTML = `
              <div class="card__avatar"></div>
              <div class="card__body">
                <div class="card__info">
                  <span class="card__author">
                    ${comment.nickname}(@${comment.username})
                  </span>
                  <span class="card__time">
                    ${comment.created_at}
                  </span>
                </div>
                <p class="card__content">${encodeHTML(comment.content)}</p>
              </div> 
        `
        document.querySelector('section').appendChild(div);
      }
    }
  };



  request.send();

  let form = document.querySelector('.board__new-comment-form');
  form.addEventListener('submit', function(e) {
    e.preventDefault();
    let content = document.querySelector('textarea[name=content]').value;
    let request = new XMLHttpRequest();
    request.open('POST', 'api_add_comment.php', true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.send("username=ooo&content=" + encodeURIComponent(content));
    request.onload = function() {
      if (this.status >= 200 && this.status < 400) {
        let resp = this.response;
        let json = JSON.parse(resp)
          if (json.ok) {
            location.reload() // 有成功新增留言就重新整理
          } else {
            alert(json.message)
          }
      }
    }
  })
  function encodeHTML(s) {
        return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
  }
</script>
</html>

tags: Week12

#week12







Related Posts

由下到上:從 TCP/IP 開始談起

由下到上:從 TCP/IP 開始談起

[重新理解 C++] TMP(3): Type deduction 和一些運用

[重新理解 C++] TMP(3): Type deduction 和一些運用

MTR04_0821

MTR04_0821


Comments