我們將進行一個完整的 PHP 專案實作,並採用 MVC 架構(Model-View-Controller)來開發專案,並整合 SESSION 或 COOKIE,同時確保程式碼具備良好的結構性和可維護性。此外,我們會注意漏洞防禦,防止常見的安全漏洞,如 SQL 注入與 XSS 攻擊。
1. MVC 架構介紹
MVC 架構:
- Model(模型):負責資料庫操作、資料處理。
- View(視圖):負責畫面呈現,顯示資料給使用者。
- Controller(控制器):負責接收請求、調用 Model 和 View,管理邏輯流程。
這種架構能將邏輯與畫面分離,提高程式的可維護性與可擴展性。
2. 專案需求:簡單登入系統
功能:
- 使用者可以註冊帳號(儲存到資料庫)。
- 使用者可以登入,登入後顯示歡迎畫面。
- 使用 SESSION 來管理登入狀態。
- 使用 COOKIE 記住使用者的登入資訊。
- 漏洞防禦:
- 防止 SQL 注入:使用 PDO 預處理語句。
- 防止 XSS 攻擊:使用
htmlspecialchars()
處理輸入資料。
3. 專案目錄結構
login_project/
│
├── index.php # 入口文件,顯示登入或註冊頁面
├── controllers/
│ └── AuthController.php # 控制器:處理邏輯
├── models/
│ └── UserModel.php # 模型:資料庫操作
├── views/
│ ├── login.php # 登入畫面
│ ├── register.php # 註冊畫面
│ └── welcome.php # 登入後歡迎畫面
├── config/
│ └── Database.php # 資料庫設定
└── assets/
└── style.css # CSS 樣式(可選)
4. 實作專案
4.1 資料庫設置
使用 phpMyAdmin 或 MySQL 建立資料庫 login_project
,並創建 users
資料表:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
);
4.2 資料庫連接設定(config/Database.php)
<?php
class Database {
private $host = "localhost";
private $dbname = "login_project";
private $username = "root";
private $password = "";
public $conn;
public function connect() {
try {
$this->conn = new PDO("mysql:host=$this->host;dbname=$this->dbname;charset=utf8", $this->username, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("資料庫連接失敗:" . $e->getMessage());
}
return $this->conn;
}
}
?>
4.3 模型(models/UserModel.php)
<?php
require_once "config/Database.php";
class UserModel {
private $conn;
public function __construct() {
$database = new Database();
$this->conn = $database->connect();
}
// 註冊使用者
public function register($username, $password) {
$hashedPassword = password_hash($password, PASSWORD_BCRYPT);
$sql = "INSERT INTO users (username, password) VALUES (:username, :password)";
$stmt = $this->conn->prepare($sql);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $hashedPassword);
return $stmt->execute();
}
// 驗證登入
public function login($username, $password) {
$sql = "SELECT * FROM users WHERE username = :username";
$stmt = $this->conn->prepare($sql);
$stmt->bindParam(':username', $username);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($password, $user['password'])) {
return true;
}
return false;
}
}
?>
4.4 控制器(controllers/AuthController.php)
<?php
require_once "models/UserModel.php";
session_start();
class AuthController {
private $userModel;
public function __construct() {
$this->userModel = new UserModel();
}
// 註冊邏輯
public function register($username, $password) {
if ($this->userModel->register($username, $password)) {
echo "註冊成功!<a href='index.php'>登入</a>";
} else {
echo "註冊失敗,使用者名稱可能已存在。";
}
}
// 登入邏輯
public function login($username, $password) {
if ($this->userModel->login($username, $password)) {
$_SESSION['username'] = $username;
setcookie("username", $username, time() + 3600); // 記住登入資訊
header("Location: views/welcome.php");
exit();
} else {
echo "登入失敗,請檢查帳號或密碼。";
}
}
// 登出邏輯
public function logout() {
session_destroy();
setcookie("username", "", time() - 3600); // 清除 COOKIE
header("Location: index.php");
exit();
}
}
?>
4.5 登入頁面(views/login.php)
<?php
require_once "../controllers/AuthController.php";
$auth = new AuthController();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
$auth->login($username, $password);
}
?>
<form method="POST" action="login.php">
帳號:<input type="text" name="username" required><br>
密碼:<input type="password" name="password" required><br>
<button type="submit">登入</button>
</form>
4.6 註冊頁面(views/register.php)
<?php
require_once "../controllers/AuthController.php";
$auth = new AuthController();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
$auth->register($username, $password);
}
?>
<form method="POST" action="register.php">
帳號:<input type="text" name="username" required><br>
密碼:<input type="password" name="password" required><br>
<button type="submit">註冊</button>
</form>
4.7 歡迎頁面(views/welcome.php)
<?php
session_start();
if (!isset($_SESSION['username'])) {
header("Location: ../index.php");
exit();
}
echo "歡迎," . $_SESSION['username'] . "!<br>";
echo "<a href='../controllers/AuthController.php?logout=true'>登出</a>";
// 處理登出邏輯
if (isset($_GET['logout'])) {
session_destroy();
setcookie("username", "", time() - 3600);
header("Location: ../index.php");
}
?>
5. 漏洞防禦
- 防止 SQL 注入
- 使用 PDO 預處理語句(
prepare()
和bindParam()
)來確保安全。
- 使用 PDO 預處理語句(
- 防止 XSS 攻擊
- 使用
htmlspecialchars()
處理使用者輸入資料。
- 使用
- 密碼加密
- 使用
password_hash()
進行加密,password_verify()
進行驗證。
- 使用
- SESSION 與 COOKIE 安全
- 使用
session_start()
管理登入狀態,並適時銷毀 SESSION。 - COOKIE 需設置安全時間限制並在登出時清除。
- 使用
這個登入系統實現了 MVC 架構 的基礎,結合 SESSION 與 COOKIE 管理登入狀態,並考慮到常見的資安問題。
透過這個專案,你能夠熟練使用 PHP 進行結構化開發,並有能力進一步學習框架如 Laravel !
One Comment