學習內容包括 PHP 文件處理:使用 fopen()
、fwrite()
、fread()
、file_get_contents()
等函式處理文件的讀寫操作。PHP MySQL 資料庫操作:使用 PDO 進行連接、插入、查詢、更新、刪除操作。資安考量:防止 SQL 注入:使用預處理語句。防止 XSS 攻擊:使用 htmlspecialchars()
處理輸入資料。學習完這些內容,你已經能夠處理基礎的檔案操作和資料庫存取,並在程式設計中兼顧安全性!
1. 文件處理(File Handling)
PHP 提供一系列函式來處理文件,例如讀取、寫入、追加等操作。
1.1 打開與寫入文件
語法:fopen()
fopen()
:打開文件並設定操作模式。常用模式:w
:寫入模式(會清空原文件內容)。a
:追加模式(在原內容後追加資料)。r
:讀取模式。
範例:創建並寫入文件
<?php
// 打開或創建一個名為 "example.txt" 的文件,寫入內容
$file = fopen("example.txt", "w");
// 寫入內容到文件
fwrite($file, "Hello, 這是第一行內容!\n");
fwrite($file, "這是第二行內容!\n");
// 關閉文件
fclose($file);
echo "文件寫入完成!";
?>
執行結果:
會在目前目錄下生成一個名為 example.txt
的文件,內容為:
Hello, 這是第一行內容!
這是第二行內容!
1.2 讀取文件內容
語法:fread()
和 file_get_contents()
fread()
:逐步讀取文件內容。file_get_contents()
:一次性讀取整個文件內容。
範例:讀取文件內容
<?php
// 讀取文件內容
$file = fopen("example.txt", "r"); // 以讀取模式打開文件
$content = fread($file, filesize("example.txt")); // 讀取全部內容
fclose($file);
echo "文件內容如下:<br>";
echo nl2br($content); // 使用 nl2br 將換行符號轉換成 HTML 換行
?>
輸出結果:
文件內容如下:
Hello, 這是第一行內容!
這是第二行內容!
1.3 追加內容到文件
範例:追加內容
<?php
// 打開文件並追加內容
$file = fopen("example.txt", "a");
fwrite($file, "這是追加的第三行內容!\n");
fclose($file);
echo "文件內容已追加!";
?>
2. 基礎資料庫操作(MySQL)
接下來,我們學習如何透過 PHP 連接 MySQL 資料庫,並執行基本的 CRUD 操作(新增、查詢、更新、刪除)。
2.1 準備工作
- 啟動 MySQL
- 使用 XAMPP 控制台啟動 MySQL 服務。
- 建立資料庫與資料表
- 使用 phpMyAdmin 建立一個名為
php_demo
的資料庫。 - 在資料庫中建立一個名為
users
的資料表:
- 使用 phpMyAdmin 建立一個名為
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL
);
3. PDO 連接 MySQL 資料庫
連接語法:
<?php
// 資料庫設定
$host = "localhost";
$dbname = "php_demo";
$username = "root";
$password = "";
try {
// 使用 PDO 連接資料庫
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
// 設定 PDO 錯誤模式為異常模式
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "成功連接到資料庫!<br>";
} catch (PDOException $e) {
// 連接失敗時輸出錯誤訊息
die("連接失敗:" . $e->getMessage());
}
?>
2. 新增資料(INSERT)
PDO 寫法:新增一筆資料
<?php
// 新增資料
try {
$sql = "INSERT INTO users (name, email) VALUES (:name, :email)";
$stmt = $pdo->prepare($sql); // 準備 SQL 語句
// 綁定參數,防止 SQL 注入
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);
// 設定變數值
$name = "Edward";
$email = "test@example.com";
// 執行 SQL 語句
$stmt->execute();
echo "新增資料成功!<br>";
} catch (PDOException $e) {
echo "新增失敗:" . $e->getMessage();
}
?>
3. 查詢資料(SELECT)
PDO 寫法:查詢所有資料
<?php
// 查詢所有資料
try {
$sql = "SELECT id, name, email FROM users";
$stmt = $pdo->query($sql); // 執行 SQL 語句並取得結果集
// 使用 fetchAll() 取得所有資料
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "使用者列表:<br>";
foreach ($users as $user) {
echo "ID:" . $user['id'] . ",姓名:" . $user['name'] . ",電子郵件:" . $user['email'] . "<br>";
}
} catch (PDOException $e) {
echo "查詢失敗:" . $e->getMessage();
}
?>
4. 更新資料(UPDATE)
PDO 寫法:更新特定資料
<?php
// 更新資料
try {
$sql = "UPDATE users SET email = :email WHERE name = :name";
$stmt = $pdo->prepare($sql); // 準備 SQL 語句
// 綁定參數
$stmt->bindParam(':email', $newEmail);
$stmt->bindParam(':name', $name);
// 設定變數值
$newEmail = "newemail@example.com";
$name = "Edward";
// 執行 SQL
$stmt->execute();
echo "更新資料成功!<br>";
} catch (PDOException $e) {
echo "更新失敗:" . $e->getMessage();
}
?>
5. 刪除資料(DELETE)
PDO 寫法:刪除特定資料
<?php
// 刪除資料
try {
$sql = "DELETE FROM users WHERE name = :name";
$stmt = $pdo->prepare($sql); // 準備 SQL 語句
// 綁定參數
$stmt->bindParam(':name', $name);
// 設定變數值
$name = "Edward";
// 執行 SQL
$stmt->execute();
echo "刪除資料成功!<br>";
} catch (PDOException $e) {
echo "刪除失敗:" . $e->getMessage();
}
?>
6. 防止 SQL 注入
PDO 使用「預處理語句 (Prepared Statements)」prepare()
和 bindParam()
防止 SQL 注入。
bindParam()
和 bindValue()
的主要差異在於參數綁定方式:
功能 | bindParam() | bindValue() |
---|---|---|
綁定內容 | 綁定變數的引用,變數值可以更改。 | 綁定當前的變數值(立即拷貝值)。 |
適用場景 | 當變數的值會在 execute() 前更改時使用。 | 當變數值是固定不變時使用。 |
範例 | $stmt->bindParam(':param', $var); | $stmt->bindValue(':param', '固定值'); |
範例:使用 prepare()
與 bindParam()
<?php
// 連接資料庫
$pdo = new PDO("mysql:host=localhost;dbname=testdb", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
// 準備 SQL 語句
$sql = "INSERT INTO users (name, email) VALUES (:name, :email)";
$statement = $pdo->prepare($sql);
// 綁定參數(綁定的是變數的引用)
$name = "Edward";
$email = "test@example.com";
$statement->bindParam(':name', $name);
$statement->bindParam(':email', $email);
// 執行 SQL
$statement->execute();
echo "資料新增成功!<br>";
// 改變變數值並再次執行
$name = "李小華";
$email = "test2@example.com";
$statement->execute();
echo "再次新增成功!<br>";
} catch (PDOException $e) {
echo "錯誤:" . $e->getMessage();
}
?>
輸出結果:
資料新增成功!
再次新增成功!
重點說明:
- 在第一次
execute()
時,$name
和$email
的值為「Edward」與「test@example.com」。 - 在第二次
execute()
前,變數值被修改為「李小華」與「test2@example.com」,因為bindParam()
綁定的是變數的引用,所以第二次執行會使用新值。
7. 綜合練習:表單處理與資料庫操作
需求:
- 使用表單輸入姓名與電子郵件。
- 將資料寫入
users
資料表。 - 將資料追加寫入
log.txt
檔案作為記錄。 - 顯示所有使用者資料。
HTML 表單:form.html
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>使用者資料輸入</title>
</head>
<body>
<h2>輸入使用者資料</h2>
<form action="process.php" method="POST">
姓名:<input type="text" name="name" required><br><br>
電子郵件:<input type="email" name="email" required><br><br>
<input type="submit" value="提交">
</form>
</body>
</html>
PHP 處理程式:process.php
<?php
// 連接資料庫
$host = "localhost";
$dbname = "php_demo";
$username = "root";
$password = "";
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 接收表單資料
$name = htmlspecialchars($_POST['name']);
$email = htmlspecialchars($_POST['email']);
// 插入資料到資料庫
$sql = "INSERT INTO users (name, email) VALUES (:name, :email)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);
$stmt->execute();
// 追加寫入 log.txt
$file = fopen("log.txt", "a");
fwrite($file, "姓名:$name,電子郵件:$email\n");
fclose($file);
echo "資料提交成功!<br>";
echo "姓名:$name,電子郵件:$email";
} catch (PDOException $e) {
echo "操作失敗:" . $e->getMessage();
}
?>