5個小時學會 PHP

我們將進行一個完整的 PHP 專案實作,並採用 MVC 架構(Model-View-Controller)來開發專案,並整合 SESSIONCOOKIE,同時確保程式碼具備良好的結構性和可維護性。此外,我們會注意漏洞防禦,防止常見的安全漏洞,如 SQL 注入與 XSS 攻擊。


1. MVC 架構介紹

MVC 架構:

  • Model(模型):負責資料庫操作、資料處理。
  • View(視圖):負責畫面呈現,顯示資料給使用者。
  • Controller(控制器):負責接收請求、調用 Model 和 View,管理邏輯流程。

這種架構能將邏輯與畫面分離,提高程式的可維護性與可擴展性。


2. 專案需求:簡單登入系統

功能:

  1. 使用者可以註冊帳號(儲存到資料庫)。
  2. 使用者可以登入,登入後顯示歡迎畫面。
  3. 使用 SESSION 來管理登入狀態。
  4. 使用 COOKIE 記住使用者的登入資訊。
  5. 漏洞防禦
    • 防止 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. 漏洞防禦

  1. 防止 SQL 注入
    • 使用 PDO 預處理語句(prepare()bindParam())來確保安全。
  2. 防止 XSS 攻擊
    • 使用 htmlspecialchars() 處理使用者輸入資料。
  3. 密碼加密
    • 使用 password_hash() 進行加密,password_verify() 進行驗證。
  4. SESSION 與 COOKIE 安全
    • 使用 session_start() 管理登入狀態,並適時銷毀 SESSION。
    • COOKIE 需設置安全時間限制並在登出時清除。

這個登入系統實現了 MVC 架構 的基礎,結合 SESSIONCOOKIE 管理登入狀態,並考慮到常見的資安問題。
透過這個專案,你能夠熟練使用 PHP 進行結構化開發,並有能力進一步學習框架如 Laravel !





主頁 » PHP » 第7節 PHP 整合學習與實作專案登入系統(採用 MVC 架構)- 5個小時學會 PHP

One Comment

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *