2021年12月22日 星期三

(PHP 與 MySQL 的互動) 2_新增資料

新增資料 (文末有完整版程式碼)

add.php:

  • insert into users(username) values("apple") 這就是一個 SQL query
  • 要放入的 values 會是一個字串,所以要用單引號或是雙引號包起來
<?php    require_once('conn.php');    $result = $conn->query('insert into users(username) values("apple")');    if (!$result) {      die($conn->error);    }      print_r($result);    ?>  

print_r($result); 的 output 會是 1,
1 就代表 true (有成功)的意思

會發現,當我在 add.php 的頁面第二次重新整理後,回到 phpMyAdmin 看,就會出現第二個 apple

優化上方的程式碼

add.php:

  • 把要放入的 values 用變數 $username 取代

在 debug 時,可以先把 $sql 印出來,看是不是正確的 SQL query

把 SQL query 獨立出來變成一個變數 $sql,這樣程式碼的可讀性比較高。在 debug 時,也可以先把 $sql 印出來 echo $sql;,看是不是正確的 SQL query

debug 完之後,記得要把 echo $sql; 拿掉

sprintf() 函式來寫 SQL query,提高程式碼可讀性

在 PHP 有一個叫做 sprintf() 的函式,建議是把 SQL query 用 sprintf() 來寫,讓整個 SQL query 字串更好寫也更好看懂:

  • 第一個參數是字串,把「動態要塞值進去的地方」變成 %d"%s",類似於 placeholder 的感覺
    • %d 代表:我要放入的是一個 number (這裡的 d 是 decimal 十進位的意思)
    • "%s" 代表:我要放入的是一個 string
  • 從第二個參數開始依序放「我要塞進去的值」

會按照順序,把 15 帶到 %d 的位置,把 $username 帶到 "%s" 的位置

<?php    require_once('conn.php');    $username = 'apple';    $sql = sprintf(      'insert into users(id, username) values(%d, "%s")',      15,      $username    );    echo $sql;    exit();    $result = $conn->query($sql);    if (!$result) {      die($conn->error);    }      print_r($result);    ?>  

組出來的 SQL query 會長這樣:

動態新增 username 到資料庫的表單

index.php:

<?php    require_once('conn.php');    $result = $conn->query('select * from users;');    if (!$result) {      die($conn->error);    }      while ($row = $result->fetch_assoc()) {      echo 'id: '. $row['id'] . '<br>';      echo 'username: ' . $row['username'] . '<br>';    }  ?>    <h2>新增 user</h2>  <form method="POST" action="add.php">    username: <input name="username">    <input type="submit">  </form>  

加上「自動跳轉的 response Header」

header('Location: index.php'); 意思就是:我要回傳一個 response Header 叫做 Location: index.php。瀏覽器接收到這個 response Header 後,就知道我的目的是要跳轉到 index.php,因此就會自動幫我跳轉回到 index.php 這個檔案去 (因為跳轉的太快了,甚至不會看到中間的 add.php 的畫面,就直接跳轉到 index.php 去了)

add.php:

<?php    require_once('conn.php');      if (empty($_POST['username'])) {      die('請輸入 username');    }    $username = $_POST['username'];    $sql = sprintf(      'insert into users(username) values("%s")',      $username    );    echo 'sql: ' . $sql. '<br>';    $result = $conn->query($sql);    if (!$result) {      die($conn->error);    }      // 如果有新增成功    echo '新增成功!';    header('Location: index.php');  ?>  

錯誤處理

上面 add.php 的程式碼,做錯誤處理的地方有兩個:

  1. 檢查 $_POST['username'] 是否為空值
  2. 檢查 SQL query 是否有執行成功,也就是 $conn->query($sql); 這段

如果 SQL query 沒有執行成功,也就是 $result 是 false,那就會執行 die($conn->error);


現在,我把 username 欄位設為 unique (代表:不能有重複的 username)
然後我到 index.php 輸入一個重複的 username 叫做 aaa,按下 submit 後就會出現一行錯誤訊息「Duplicate entry 'aaa' for key 'username'」,就是因為在執行到 $conn->query($sql); 時發生錯誤($result 會是 false),因此這行錯誤訊息就是從 die($conn->error); 這行印出來的

排序「資料庫的讀取結果」

「資料庫的讀取結果」的排序不一定會按照 id 順序,如果想要按照 id 排序的話,就在 index.php 的 SQL query 加上 order by id asc 或是 order by id desc

  • asc 是「由小到大」排列
    ascending 就是 increasing 的意思
<?php    require_once('conn.php');    $result = $conn->query('select * from users order by id asc;');    if (!$result) {      die($conn->error);    }      while ($row = $result->fetch_assoc()) {      echo 'id: '. $row['id'] . '<br>';      echo 'username: ' . $row['username'] . '<br>';    }  ?>    <h2>新增 user</h2>  <form method="POST" action="add.php">    username: <input name="username">    <input type="submit">  </form>  
  • desc 是「由大到小」排列
    descending 就是下降的意思
<?php    require_once('conn.php');    $result = $conn->query('select * from users order by id desc;');    if (!$result) {      die($conn->error);    }      while ($row = $result->fetch_assoc()) {      echo 'id: '. $row['id'] . '<br>';      echo 'username: ' . $row['username'] . '<br>';    }  ?>    <h2>新增 user</h2>  <form method="POST" action="add.php">    username: <input name="username">    <input type="submit">  </form>  

新增資料的程式碼,完整版如下:

conn.php:

<?php    $server_name = 'localhost';    $username = 'saffran';    $password = 'rox';    $db_name = 'saffran_db';      $conn = new mysqli($server_name, $username, $password, $db_name);      if ($conn->connect_error) {      die('資料庫連線錯誤:' . $conn->connect_error);    }      $conn->query('SET NAMES UTF8');    $conn->query('SET time_zone = "+8:00"');  ?>  

index.php:

<?php    require_once('conn.php');    $result = $conn->query('select * from users order by id desc;');    if (!$result) {      die($conn->error);    }      while ($row = $result->fetch_assoc()) {      echo 'id: '. $row['id'] . '<br>';      echo 'username: ' . $row['username'] . '<br>';    }  ?>    <h2>新增 user</h2>  <form method="POST" action="add.php">    username: <input name="username">    <input type="submit">  </form>  

add.php:

<?php    require_once('conn.php');      if (empty($_POST['username'])) {      die('請輸入 username');    }    $username = $_POST['username'];    $sql = sprintf(      'insert into users(username) values("%s")',      $username    );    $result = $conn->query($sql);    if (!$result) {      die($conn->error);    }      // 如果有新增成功    header('Location: index.php');  ?>  

沒有留言:

張貼留言

(Centos-7s) 更新: 網卡名稱改回 eth0 的方法

將 CentOS 7 網卡名稱修改, 用回 Eth0 的方法:   1) # vi /etc/sysconfig/grub 內容大概是這樣:   GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release...