PHP & MySQL


Posted by Nicolakacha on 2020-09-06

Apache 與 PHP 原理

request(test.php) ⇒ apache(server) ⇒ php ⇒ output ⇒ apache ⇒ response
Server:專門處理 request 和 response 的程式
網址的規則是由 server 來決定,Apache預設的設定是檔案路徑

資料庫系統簡介

資料庫:專門處理資料的程式

關聯式資料庫 relational database SQL: MySQL, PostgreSQL
// 像不同的 excel 表格但都有共用索引的參數

非關聯式資料庫 NoSQL: MongoDB, Microsoft SQL
// 存的有點像是 JSON 一個個的物件

MySQL

phpmyadmin: 一套 GUI 的 資料庫管理介面

Table 表格基礎


主鍵 Primary Key - 這個資料最主要的資料
Unique - 保證資料不重複
Index - 索引,對很常會需要查資料的欄位

MySQL 語法簡介

Select 查詢資料
SELECT * FROM qoo // 查詢全部資料
SELECT id FROM qoo // 查詢 id
SELECT id as name FROM qoo //查詢 id 並顯示成 name
SELECT id as name FROM WHERE id = 2 // where 查詢條件
SELECT * FROM qoo WHERE username='nicolas' and id=1 // where 查詢條件,可用 and 或 or 篩選多筆條件

Insert 新增資料
INSERT INTO qoo(username, content) VALUES ('Mike', 'yoyoyo')

Update 更新資料
UPDATE qoo SET username='Nill', content ='lalalala' WHERE id=2
一定要記得用 WHERE 選到要改的那筆資料

Delete 刪除資料
DELETE FROM qoo WHERE id=2

很多時候我們不是真的要把資料刪掉,一般會新增一個欄位叫 if deleted,在前台刪除資料時就只是把資料的 if deleted 設為 1,而不是真的刪掉資料,可以避免使用者在前台誤刪資料,畢竟對使用者而言,資料沒有出現就等於資料被刪掉了。

Join

PHP 執行流程


有設定過 server 才會執行 PHP 檔,不然就會直接輸出文字檔

<h1>Now: <?php echo date("Y-m-d H:i:s") ?></h1>

前後端溝通 GET 與 POST

前端

<?php
  echo "I am Nicolas! Yo!"
?>

<form method="GET" action="data.php">
  name: <input type="text" name="name">
  age: <input type="text" name="age">
  <input type="submit">
</form>

後端

<?php
  if (empty($_GET['name'] || empty($_GET['age']))) {
    echo '資料有缺,請再次填寫<br>';
    exit();
  }

  echo "Hello " . $_GET['name'] . "<br>";
  echo "Your age is " . $_GET['age'] . "<br><br>";

  print_r($_GET);
?>

從 PHP 連線到 MySQL 資料庫

Object Oriented style

$server_name = 'localhost';
$username = 'huli';
$password = 'huli';
$db_name = 'huli';

$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"');

放到 GitHub 的時候會排除 conn.php,因為會上傳密碼

Procedural style

$server_name = 'localhost';
$username = 'huli';
$password = 'huli';
$db_name = 'huli';

$conn = mysqli_connect($server_name, $username, $password, $db_name);

// Check connection
if (mysqli_connect_errno()) {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

PHP 與 MySQL 的互動 CRUD

讀取資料範例

  • Object Oriented style
    ```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'] . '
';
echo "username:" . $row['username'] . '
';
}


- Procedural style
```php
require_once('conn.php');

// Create Query
$query = "SELECT * FROM users";

// Get Result
$result = mysqli_query($conn, $query);
if (!$result) {
  die();
}

// Fetch Data
$users= mysqli_fetch_all($result, MYSQLI_ASSOC)
mysqli_free_result($result)

// Close Connection
mysqli_close($conn);
<?php foreach($users as $user) : ?>
    <div class="comment">
        <h3><?php echo $user['nickname']; ?></h3>
        <p><?php echo $user['body']; ?></p>
    </div>
<?php endforeach; ?>

新增資料範例

<?php
  require_once('conn.php');
  $username = 'apple';
  $sql = "insert into users(username) values('" . $username ."')";
  echo $sql;
  $result = $conn->query($sql);

  if (!$result) {
    die($conn->error);
  }

  print_r($result);

?>

add.php

<?php
  require_once('conn.php');
    //檢查 username
  if(empty($_POST['username'])) {
    die('請輸入 username');
  }

  $username = $_POST['username'];
//利用 spintf 方法
  $sql = sprintf(
    "insert into users(username) values('%s')",
    $username
  );
  echo 'SQL: '. $sql . '<br>';
  $result = $conn->query($sql);

    //看有沒有成功
  if (!$result) {
    die($conn->error);
  }
  //跳轉回 index.php
    header("Location": "index.php");
?>

<!-- <a href="index.php">go back</a> -->

index.php

<?php
  echo "Hi my name is Nicolas";
  require_once('conn.php');

  $result = $conn->query('SELECT * from users ORDER BY id');
  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 type="text" name="username">
<input type="submit">
</form>

刪除資料範例
delete.php
用 GET 的方式把 id 帶去 delete.php 這個檔案

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

  if(empty($_GET['id'])) {
    die('請輸入 id');
  }

  $id = $_GET['id'];
  $sql = sprintf(
    "DELETE from users where id = %d",
    $id
  );
  echo $sql . '<br>';
  $result = $conn->query($sql);
  if (!$result) {
    die($conn->error);
  }

    if ($conn->affected_rows >= 1) {
    echo '刪除成功';
  } else {
    echo '查無資料';
  }

  header("Location: index.php");
?>

index.php

<?php
  echo "Hi my name is Nicolas";

  require_once('conn.php');

  $result_time = $conn->query('SELECT now() as n');
  if (!$result_time) {
    die($conn->error);    
  }
  // print_r($result);
  $row = $result_time->fetch_assoc();
  echo '<br>now: ' . $row['n'] . '<br><br>';

  $result = $conn->query('SELECT * from users ORDER BY id');
  if (!$result) {
    die($conn->error);
  }
  while ($row = $result->fetch_assoc()) {
    echo 'id: ' . $row['id'];
    echo "<a href='delete.php?id=". $row['id'] ."'>刪除</a>";
    echo '<br>';
    echo 'username ' . $row['username'] . '<br>';
  }
?>

<h2>新增 USER</h2>
<form method="POST" action="add.php">
username: <input type="text" name="username">
<input type="submit">
</form>

一般的刪除不會用 GET 來做,這裡只是為了示範
$conn->affected_rows 查看被影響的列數,用來看是否有刪除成功

編輯資料範例

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

  if (empty($_POST['id']) || empty($_POST['username'])) {
    die('請輸入 id 與 username');
  }

  $id = $_POST['id'];
  $username = $_POST['username'];
  $sql = sprintf(
    "update users set username='%s' where id=%d",
    $username,
    $id
  );
  echo $sql . '<br>';
  $result = $conn->query($sql);
  if (!$result) {
    die($conn->error);
  }

  header("Location: index.php");
?>

指令快查表

<?php
  // 連線資料庫
  $server_name = 'localhost';
  $username = 'huli';
  $password = 'huli';
  $db_name = 'huli';

  $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"');

  // 新增資料
  $username = $_POST['username'];
  $sql = sprintf(
    "insert into users(username) values('%s')",
    $username
  );
  $result = $conn->query($sql);
  if (!$result) {
    die($conn->error);
  }

  // 讀取資料
  $result = $conn->query("SELECT * FROM users ORDER BY id ASC;");
  if (!$result) {
    die($conn->error);
  }

  while ($row = $result->fetch_assoc()) {
    echo "id:" . $row['id'];
  }

  // 修改資料
  $id = $_POST['id'];
  $username = $_POST['username'];
  $sql = sprintf(
    "update users set username='%s' where id=%d",
    $username,
    $id
  );
  echo $sql . '<br>';
  $result = $conn->query($sql);
  if (!$result) {
    die($conn->error);
  }

  // 刪除資料
  $id = $_GET['id'];
  $sql = sprintf(
    "delete from users where id = %d",
    $id
  );
  $result = $conn->query($sql);
  if (!$result) {
    die($conn->error);
  }

  if ($conn->affected_rows >= 1) {
    echo '刪除成功';
  } else {
    echo '查無資料';
  }
?>

怎麼使用 cookie

Cookie 是一小片段資料,Client 端透過瀏覽器發送 Request 給 Server,Server 端回傳 Response 時,在 Header 內 Set-Cookie,把資料寫到 Cookie 內。這個 Cookie 會被儲存在 Client 端的瀏覽器內,Client 端下次再次發出 Request 給 Server 時,request 會自動把儲存在瀏覽器內的 Cookie 帶上去。這樣就可以達成識別、紀錄、追蹤 Client 端的狀態。所以也就是說,利用 Cookie 就可以實現不同的 Session,解決 HTTP Request 無狀態的問題。不同瀏覽器對 Cookie 數量與大小的限制也不同,

存取 cookie

$name = "cookie";
$value = "100";
$expiration = time() + (60*60*24*7);
setcookie($name, $value, $expiration);

取用 cookie

if(issent($_COOKIE['cookie']) {
    $cookie = $_COOKIE['cookie']; 
    echo $cookie;
} else {
    $cookie = "";
}

// 100

銷毀 cookie

setcookie($name, $value, time() - 3600);

如何使用 SESSION

存取 session

//要使用 Session,都要在開頭使用 session_start()
session_start();

$username = htmlspecialchars($_POST['username']);

//把資料存在 Session 對應的 key 裡面
$_SEESION['username'] = $username;

取用 session

//要使用 Session,都要在開頭使用 session_start()
session_start();

//如果 session 內有存過 username,
//則宣告變數 $username 為剛才存的 $_SESSION['username'] 
if(isset($_SESSION['username'])) {
    $username = $_SESSION['username'];
  }

銷毀 session

    session_start();
  session_destroy();
  header('Location: ./index.php')

Session & Cookie 補充資料

白話 Session 與 Cookie:從經營雜貨店開始

淺談 Session 與 Cookie:一起來讀 RFC

深入 Session 與 Cookie:Express、PHP 與 Rails 的實作

[JavaScript] Cookie、LocalStorage、SessionStorage 三種差異

HTTP Session 攻擊與防護 | DEVCORE 戴夫寇爾


#PHP #MySQL #程式導師計畫







Related Posts

React Form: Redux Form vs React Final Form vs Formik and Yup

React Form: Redux Form vs React Final Form vs Formik and Yup

用 Python 自學程式設計:程式設計思維入門

用 Python 自學程式設計:程式設計思維入門

React 我不知道的事 & 下半年期許

React 我不知道的事 & 下半年期許


Comments