PHP + MySQL 是 Web 開發的「黃金搭檔」,支撐了早期 Facebook、Yahoo、WordPress 等億級應用。本文系統梳理環境搭建 (Linux/Windows)、基礎語法、資料庫交互、表單處理、會話管理、安全防護、效能優化全棧知識,適合零基礎入門與進階鞏固。
# Ubuntu
sudo apt update && sudo apt install -y apache2 mysql-server php php-mysql libapache2-mod-php
sudo mysql_secure_installation
# CentOS/RHEL
sudo yum install -y httpd mariadb-server php php-mysql
sudo systemctl enable --now httpd mariadb
sudo mysql_secure_installation
D:\Server。httpd.conf 載入 php_module、設置 DirectoryIndex index.php。php.ini 開啟 mysqli、pdo_mysql、date.timezone。<?php
// 變量、常量、數據類型
$name = "Zhang San"; // 字符串
$age = 25; // 整數
$price = 19.9; // 浮點數
$active = true; // 布爾
define('SITE_URL', 'https://example.com'); // 常量
// 數組
$user = ['name' => 'Li Si', 'email' => 'li@example.com'];
$users = [$user, ['name' => 'Wang Wu', 'email' => 'wang@example.com']];
// 流程控制
if ($age >= 18) { echo "成年"; } else { echo "未成年"; }
foreach ($users as $u) { echo $u['name']; }
// 函數
function greet($name) { return "Hello, $name!"; }
echo greet('Zhao Liu');
-- 登入
mysql -u root -p
-- 建庫建表
CREATE DATABASE demo CHARACTER SET utf8mb4;
USE demo;
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL,
password_hash CHAR(60) NOT NULL, -- bcrypt 輸出長度 60
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- CRUD
INSERT INTO users (username, email, password_hash) VALUES ('test', 'test@ex.com', '$2y$10$...');
SELECT * FROM users WHERE username = 'test';
UPDATE users SET email = 'new@ex.com' WHERE username = 'test';
DELETE FROM users WHERE username = 'test';
<?php
$dsn = 'mysql:host=localhost;dbname=demo;charset=utf8mb4';
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 真預處理
];
$pdo = new PDO($dsn, 'app_user', 'secure_pass', $opt);
// 插入 (預處理防注入)
$stmt = $pdo->prepare('INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)');
$stmt->execute(['user1', 'user1@ex.com', password_hash('pass123', PASSWORD_BCRYPT)]);
// 查詢
$stmt = $pdo->prepare('SELECT id, username, email FROM users WHERE username = ?');
$stmt->execute(['user1']);
$user = $stmt->fetch();
print_r($user);
<!-- register.html -->
<form method="post" action="register.php">
用戶名: <input name="username" required pattern="\w{3,20}"><br>
郵箱: <input name="email" type="email" required><br>
密碼: <input name="password" type="password" required minlength="8"><br>
<button type="submit">註冊</button>
</form>
<?php
// register.php
require 'pdo.php'; // 包含上述 $pdo
$username = trim($_POST['username'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
if (!$username || !$email || !$password) {
die('請填寫完整信息');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
die('郵箱格式錯誤');
}
// 檢查用戶名是否存在
$stmt = $pdo->prepare('SELECT 1 FROM users WHERE username = ?');
$stmt->execute([$username]);
if ($stmt->fetch()) {
die('用戶名已存在');
}
// 密碼哈希存儲
$hash = password_hash($password, PASSWORD_BCRYPT);
$stmt = $pdo->prepare('INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)');
$stmt->execute([$username, $email, $hash]);
echo '註冊成功!';
<?php
// login.php
session_start();
require 'pdo.php';
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$remember = isset($_POST['remember']);
$stmt = $pdo->prepare('SELECT id, password_hash FROM users WHERE username = ?');
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password_hash'])) {
$_SESSION['user_id'] = $user['id'];
// 記住我:設置長效 Cookie
if ($remember) {
$token = bin2hex(random_bytes(32));
$pdo->prepare('INSERT INTO remember_tokens (user_id, token, expires) VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 30 DAY))')
->execute([$user['id'], $token]);
setcookie('remember_token', $token, time() + 30*86400, '/', '', true, true);
}
header('Location: dashboard.php');
exit;
}
echo '用戶名或密碼錯誤';
| 風險 | 防護措施 |
|---|---|
| SQL 注入 | 全量使用 PDO 預處理、嚴禁字符串拼接 SQL |
| XSS 跨站腳本 | 輸出轉義 htmlspecialchars($str, ENT_QUOTES, 'UTF-8')、CSP 頭 |
| CSRF 跨站請求偽造 | 表單隱藏 Token、SameSite Cookie、雙重 Cookie 驗證 |
| 密碼洩露 | bcrypt/argon2 哈希、HTTPS 傳輸、禁止明文日志 |
| 文件上傳執行 | 類型白名單、重命名存儲、上傳目錄禁用 PHP 引擎、病毒掃描 |
| 會話劫持 | HTTPS、HttpOnly/Secure Cookie、會話 ID 再生成、IP/UA 綁定 |
opcache.enable=1)。PHP + MySQL 開發核心路徑:環境標準化 → PDO 預處理 → 表單驗證 → 密碼哈希 → 會話 Token → 安全清單 → 優化閉環。建議新專案直接使用 Laravel / Symfony / Hyperf 等現代框架,內置上述最佳實踐,專注業務邏輯而非重複造輪子。