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:Express、PHP 與 Rails 的實作