PHP : 從零開始
這是一篇關於PHP從0開始的小電子書!
前言:PHP 在做什麼
PHP(PHP: Hypertext Preprocessor)是在伺服器端執行的程式語言。使用者用瀏覽器請求一個 .php 網址,Web 伺服器執行 PHP,通常查資料庫、組裝邏輯,最後輸出 HTML / JSON 回傳。
sequenceDiagram participant B as 瀏覽器 participant S as Apache/Nginx + PHP participant D as MySQL B->>S: GET /users.php S->>D: SELECT * FROM users D->>S: 資料列 S->>S: PHP 組裝回應 S->>B: HTML 或 JSON
PHP 並非輸出HTML而是嵌入HTML標籤中,以特殊的
<?php?>標籤來宣告PHP片段。
第 0 章:開發環境
快速開始
前往codesandbox線上編輯器,建立帳號後建立php專案

本地環境安裝
以下提供如果想要在自己本地安裝環境:
| 元件 | 作用 |
|---|---|
| PHP 8.2+ | 語言執行環境(建議 8.1 以上) |
| Web Server | Apache 或 Nginx(或用 PHP 內建伺服器開發) |
| MySQL / MariaDB / SQLite | 儲存資料(進階章節) |
| 編輯器 | VS Code、PhpStorm |
一鍵安裝包(擇一):
在專案目錄執行:
php -S localhost:8000Code language: CSS (css)
瀏覽 http://localhost:8000/index.php 即可。適合學習,正式環境請用 Apache/Nginx。
info.php:
<?php
phpinfo();Code language: HTML, XML (xml)
看到紫色資訊頁代表成功。正式環境務必刪除。
CLI 模式
PHP 不只能跑網頁,也能在終端機執行:
php -r "echo 2 + 2;"
php script.phpCode language: JavaScript (javascript)
建議 VS Code 擴充
- PHP Intelephense
- PHP Debug(Xdebug)
- EditorConfig
第 1 章:第一支 PHP 程式
基本規則
- 程式寫在
<?php ... ?>內(檔尾可省略?>,建議省略避免多餘空白) - 陳述以
;結尾 - 副檔名
.php
<?php
echo 'Hello, World!';Code language: HTML, XML (xml)
與 HTML 混寫
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title><?= '我的網站' ?></title>
</head>
<body>
<h1><?php echo '歡迎'; ?></h1>
<p>現在時間:<?php echo date( 'Y-m-d H:i' ); ?></p>
</body>
</html>Code language: HTML, XML (xml)
<?= ... ?> 是 <?php echo ... ?> 的簡寫。
註解
// 單行註解
# 也是單行
/*
多行
註解
*/Code language: PHP (php)
第 2 章:變數、型別與運算子
變數
以 $ 開頭,區分大小寫:
<?php
$name = 'Alice';
$age = 25;
$price = 19.99;
$active = true;Code language: HTML, XML (xml)
常見型別
| 型別 | 範例 |
|---|---|
string | 'hello' |
int | 42 |
float | 3.14 |
bool | true / false |
array | [1, 2, 3] |
null | null |
object | new User() |
PHP 8+ 可宣告型別:
function add( int $a, int $b ): int {
return $a + $b;
}Code language: PHP (php)
寬鬆轉型
'5' + 2; // 7(字串自動轉數字)Code language: JavaScript (javascript)
實務上應明確轉型:
$id = (int) $_GET['id'];
$price = (float) $row['price'];Code language: PHP (php)
重要運算子
$a + $b; // 加
$a . $b; // 字串連接(極常用)
$a === $b; // 嚴格相等(型別+值)
$a ?? $b; // $a 為 null 則用 $b
$a ?: $b; // $a 為假值則用 $b
$a <=> $b; // 太空船:比較大小回傳 -1/0/1Code language: PHP (php)
字串(兩種引號)
$name = 'Bob';
echo "Hello, $name"; // 雙引號可插值
echo 'Hello, $name'; // 單引號大部分原樣輸出Code language: PHP (php)
第 3 章:流程控制
if / elseif / else
<?php
$score = 85;
if ( $score >= 90 ) {
echo 'A';
} elseif ( $score >= 80 ) {
echo 'B';
} else {
echo 'C';
}Code language: HTML, XML (xml)
替代語法(模板常用)
<?php if ( $logged_in ) : ?>
<p>歡迎回來</p>
<?php else : ?>
<p>請登入</p>
<?php endif; ?>Code language: HTML, XML (xml)
switch、match(PHP 8+)
<?php
$role = 'editor';
switch ( $role ) {
case 'admin':
$level = 3;
break;
case 'editor':
$level = 2;
break;
default:
$level = 1;
}
// match 更簡潔,必須涵蓋所有情況或 default
$label = match ( $role ) {
'admin' => '管理員',
'editor' => '編輯',
default => '訪客',
};Code language: HTML, XML (xml)
迴圈
<?php
for ( $i = 0; $i < 5; $i++ ) {
echo $i;
}
$items = [ 'PHP', 'MySQL', 'HTML' ];
foreach ( $items as $item ) {
echo $item;
}
foreach ( $user as $key => $value ) {
echo "$key: $value";
}
while ( $row = $stmt->fetch() ) {
// 處理每一列
}Code language: HTML, XML (xml)
break / continue
foreach ( $items as $item ) {
if ( $item === 'skip' ) {
continue; // 跳過本次
}
if ( $item === 'stop' ) {
break; // 結束迴圈
}
}Code language: PHP (php)
第 4 章:函式
定義與回傳
<?php
function greet( string $name ): string {
return 'Hello, ' . $name;
}
echo greet( 'World' );Code language: HTML, XML (xml)
預設參數與命名參數
function paginate( int $page = 1, int $per_page = 10 ): array {
return [ 'page' => $page, 'per_page' => $per_page ];
}
paginate( per_page: 20, page: 2 ); // PHP 8 命名參數Code language: PHP (php)
可變參數
function sum( int ...$nums ): int {
return array_sum( $nums );
}
sum( 1, 2, 3 ); // 6Code language: PHP (php)
防止重複定義
if ( ! function_exists( 'my_helper' ) ) {
function my_helper() {
// ...
}
}Code language: JavaScript (javascript)
匿名函式與閉包
$multiplier = 3;
$fn = function ( int $n ) use ( $multiplier ): int {
return $n * $multiplier;
};
echo $fn( 4 ); // 12Code language: PHP (php)
箭頭函式(PHP 7.4+)
$double = fn( int $n ) => $n * 2;Code language: PHP (php)
第 5 章:陣列
索引與關聯陣列
<?php
$list = [ 'apple', 'banana' ];
$user = [
'id' => 1,
'name' => 'Alice',
'role' => 'admin',
];
echo $user['name'];Code language: HTML, XML (xml)
常用函式
count( $arr );
empty( $arr );
isset( $arr['key'] );
array_key_exists( 'key', $arr );
$arr[] = 'new'; // 追加
array_push( $arr, 'a', 'b' );
array_pop( $arr );
array_map( fn( $x ) => $x * 2, [ 1, 2, 3 ] );
array_filter( $arr, fn( $x ) => $x > 0 );
in_array( 'apple', $list, true ); // 嚴格模式Code language: PHP (php)
解構
[ $first, $second ] = [ 10, 20 ];
[ 'name' => $name ] = $user;Code language: PHP (php)
** Spread**
$merged = [ ...$a, ...$b ];Code language: PHP (php)
第 6 章:字串處理
strlen( $s );
mb_strlen( $s, 'UTF-8' ); // 中文用這個
strpos( $haystack, $needle );
str_contains( $haystack, 'x' ); // PHP 8+
str_starts_with( $s, 'pre' );
str_ends_with( $s, 'suf' );
str_replace( 'old', 'new', $s );
preg_match( '/^\d+$/', $s ); // 正規表示式
trim( $s );
explode( ',', $s );
implode( '-', $arr );
sprintf( '%s 有 %d 筆', $name, $count );
number_format( 12345.6, 2 ); // 1,234.56Code language: PHP (php)
輸出跳脫(安全基礎)
echo htmlspecialchars( $text, ENT_QUOTES, 'UTF-8' );Code language: PHP (php)
防止 XSS:任何來自使用者或資料庫、要顯示在 HTML 的字串都應跳脫。
第 7 章:表單與超全域變數
超全域變數
在任何函式內都可存取:
| 變數 | 內容 |
|---|---|
$_GET | URL 查詢 ?page=2 |
$_POST | POST body |
$_SERVER | 請求方法、URI、IP |
$_FILES | 上傳檔案 |
$_COOKIE | Cookie |
$_SESSION | Session(需 session_start()) |
$_ENV | 環境變數 |
GET 範例search.php:
<?php
$query = isset( $_GET['q'] ) ? trim( $_GET['q'] ) : '';
?>
<form method="get">
<input type="search" name="q" value="<?= htmlspecialchars( $query, ENT_QUOTES, 'UTF-8' ) ?>">
<button type="submit">搜尋</button>
</form>
<?php if ( $query !== '' ) : ?>
<p>你搜尋了:<?= htmlspecialchars( $query, ENT_QUOTES, 'UTF-8' ) ?></p>
<?php endif; ?>Code language: HTML, XML (xml)
POST 範例
<?php
$errors = [];
$name = '';
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
$name = trim( $_POST['name'] ?? '' );
if ( $name === '' ) {
$errors[] = '姓名不可空白';
}
if ( ! $errors ) {
// 寫入資料庫或處理邏輯
header( 'Location: /success.php' );
exit;
}
}
?>Code language: HTML, XML (xml)
重導向後 exit 很重要,避免繼續執行下方程式。
$_SERVER 常用鍵
$_SERVER['REQUEST_METHOD']; // GET / POST
$_SERVER['REQUEST_URI']; // /path?query=1
$_SERVER['HTTP_HOST'];
$_SERVER['REMOTE_ADDR']; // 客戶端 IP(可被 proxy 影響)Code language: PHP (php)
第 8 章:Session、Cookie 與狀態
HTTP 本身是無狀態的;要記住「已登入」需 Session 或 Cookie。
Session
<?php
session_start();
$_SESSION['user_id'] = 42;
$_SESSION['username'] = 'alice';
// 讀取
$user_id = $_SESSION['user_id'] ?? null;
// 登出
session_destroy();Code language: HTML, XML (xml)
流程:
sequenceDiagram
participant B as 瀏覽器
participant S as PHP 伺服器
B->>S: POST /login(帳密)
S->>S: 驗證成功,session_start()
S->>S: $_SESSION['user_id'] = 1
S->>B: Set-Cookie: PHPSESSID=abc123
B->>S: GET /dashboard(帶 Cookie)
S->>S: 依 PHPSESSID 讀取 Session
S->>B: 已登入頁面Code language: JavaScript (javascript)
Cookie
setcookie( 'theme', 'dark', [
'expires' => time() + 86400 * 30,
'path' => '/',
'httponly' => true,
'samesite' => 'Lax',
] );
$theme = $_COOKIE['theme'] ?? 'light';Code language: PHP (php)
敏感資料(如密碼)不要放 Cookie 明文;Session ID 透過 Cookie 傳即可。
第 9 章:檔案、路徑與引入
include / require
require_once __DIR__ . '/config.php';
include __DIR__ . '/partials/header.php';Code language: PHP (php)
| 語法 | 找不到檔案時 |
|---|---|
include | Warning,繼續 |
require | Fatal,停止 |
*_once | 只載入一次 |
__DIR__ 是目前檔案所在目錄的絕對路徑,比相對路徑可靠。
讀寫檔案
$content = file_get_contents( 'data.txt' );
file_put_contents( 'log.txt', $line, FILE_APPEND );
$handle = fopen( 'big.csv', 'r' );
while ( ( $row = fgetcsv( $handle ) ) !== false ) {
// 處理每一行
}
fclose( $handle );Code language: PHP (php)
JSON 檔當簡易資料庫
$data = json_decode( file_get_contents( 'users.json' ), true );
file_put_contents( 'users.json', json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE ) );Code language: PHP (php)
第 10 章:物件導向 PHP
類別與物件
<?php
class User {
public int $id;
public string $name;
public function __construct( int $id, string $name ) {
$this->id = $id;
$this->name = $name;
}
public function greet(): string {
return 'Hi, ' . $this->name;
}
}
$user = new User( 1, 'Alice' );
echo $user->greet();Code language: HTML, XML (xml)
可見性
| 修飾符 | 存取範圍 |
|---|---|
public | 到處可用 |
protected | 類別內與子類別 |
private | 僅類別內 |
建構子屬性提升(PHP 8+)
class Product {
public function __construct(
public string $name,
public float $price,
) {}
}Code language: PHP (php)
繼承與介面
interface Notifiable {
public function notify( string $message ): void;
}
class EmailNotifier implements Notifiable {
public function notify( string $message ): void {
mail( 'user@example.com', 'Notice', $message );
}
}Code language: PHP (php)
靜態、常數、列舉
class MathUtil {
public const PI = 3.14159;
public static function add( int $a, int $b ): int {
return $a + $b;
}
}
enum Status: string {
case Draft = 'draft';
case Published = 'published';
}Code language: PHP (php)
魔術方法
public function __toString(): string { return $this->name; }
public function __get( string $key ) { /* ... */ }Code language: PHP (php)
第 11 章:命名空間、Composer 與自動載入
命名空間
避免類別名稱衝突:
<?php
namespace App\Models;
class User {
// ...
}Code language: HTML, XML (xml)
<?php
namespace App\Controllers;
use App\Models\User;
class UserController {
public function show( int $id ): void {
$user = new User( $id, 'Bob' );
}
}Code language: HTML, XML (xml)
Composer
PHP 的套件管理器:
composer init
composer require monolog/monologCode language: JavaScript (javascript)
composer.json:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}Code language: JSON / JSON with Comments (json)
composer dump-autoload
入口:
<?php
require __DIR__ . '/vendor/autoload.php';
use App\Models\User;Code language: HTML, XML (xml)
PSR 標準(了解即可)
- PSR-4:自動載入目錄對應
- PSR-12:程式碼風格
- 現代 PHP 專案幾乎都用 Composer + 命名空間
第 12 章:資料庫與 PDO
關聯式資料庫概念
這裡簡單說明一下資料庫學習中常見的幾個詞彙。
| 名詞 | 說明 |
|---|---|
| 資料表 Table | 如 users、posts |
| 列 Row | 一筆記錄 |
| 欄 Column | 欄位如 id、email |
| 主鍵 Primary Key | 唯一識別,常為 id |
| 外鍵 Foreign Key | 關聯另一張表 |
建立連線(PDO)
<?php
$dsn = 'mysql:host=127.0.0.1;dbname=app;charset=utf8mb4';
$user = 'root';
$pass = '';
$pdo = new PDO( $dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
] );Code language: HTML, XML (xml)
查詢(Prepared Statement)
// 讀取
$stmt = $pdo->prepare( 'SELECT * FROM users WHERE id = :id' );
$stmt->execute( [ 'id' => $user_id ] );
$row = $stmt->fetch();
// 列表
$stmt = $pdo->query( 'SELECT id, name FROM users ORDER BY id DESC' );
$users = $stmt->fetchAll();
// 新增
$stmt = $pdo->prepare( 'INSERT INTO users (name, email) VALUES (:name, :email)' );
$stmt->execute( [
'name' => $name,
'email' => $email,
] );
$new_id = $pdo->lastInsertId();
// 更新
$stmt = $pdo->prepare( 'UPDATE users SET name = :name WHERE id = :id' );
$stmt->execute( [ 'name' => $name, 'id' => $id ] );
// 刪除
$stmt = $pdo->prepare( 'DELETE FROM users WHERE id = :id' );
$stmt->execute( [ 'id' => $id ] );Code language: PHP (php)
永遠用佔位符,不要拼接使用者輸入進 SQL 字串。
交易 Transaction
$pdo->beginTransaction();
try {
$pdo->prepare( 'UPDATE accounts SET balance = balance - :amt WHERE id = 1' )
->execute( [ 'amt' => 100 ] );
$pdo->prepare( 'UPDATE accounts SET balance = balance + :amt WHERE id = 2' )
->execute( [ 'amt' => 100 ] );
$pdo->commit();
} catch ( Exception $e ) {
$pdo->rollBack();
throw $e;
}Code language: PHP (php)
簡易 Repository 模式
class UserRepository {
public function __construct( private PDO $pdo ) {}
public function find( int $id ): ?array {
$stmt = $this->pdo->prepare( 'SELECT * FROM users WHERE id = :id' );
$stmt->execute( [ 'id' => $id ] );
$row = $stmt->fetch();
return $row ?: null;
}
}Code language: PHP (php)
第 13 章:錯誤處理與除錯
錯誤等級
| 等級 | 說明 |
|---|---|
| Notice | 可疑但不致命 |
| Warning | 有問題但繼續 |
| Fatal Error | 程式停止 |
開發環境設定php.ini 或程式開頭:
ini_set( 'display_errors', '1' );
ini_set( 'display_startup_errors', '1' );
error_reporting( E_ALL );Code language: JavaScript (javascript)
正式環境應關閉 display_errors,改寫 log。
例外 Exception
try {
if ( $age < 0 ) {
throw new InvalidArgumentException( '年齡不可為負' );
}
$result = risky_operation();
} catch ( InvalidArgumentException $e ) {
echo '參數錯誤:' . $e->getMessage();
} catch ( Throwable $e ) {
error_log( $e->getMessage() );
echo '系統忙碌中';
}Code language: PHP (php)
除錯技巧
error_log( print_r( $data, true ) );
var_dump( $var ); // 僅開發用Code language: PHP (php)
Xdebug:斷點除錯、堆疊追蹤,PhpStorm / VS Code 可連接。
常見錯誤
| 訊息 | 常見原因 |
|---|---|
Parse error: syntax error | 少分號、括號不配對 |
Undefined variable | 變數未賦值 |
Call to undefined function | 函式名打錯或未引入 |
Class not found | 命名空間或 autoload 問題 |
| 白畫面 | Fatal Error + 關閉 display_errors |
第 14 章:安全實務
1. 跳脫輸出(XSS 防護)
function e( string $value ): string {
return htmlspecialchars( $value, ENT_QUOTES, 'UTF-8' );
}
echo '<p>' . e( $user_input ) . '</p>';Code language: PHP (php)
2. 預處理語句(SQL Injection 防護)
// 危險:絕對不要這樣
// "SELECT * FROM users WHERE id = {$_GET['id']}";
$stmt = $pdo->prepare( 'SELECT * FROM users WHERE id = :id' );
$stmt->execute( [ 'id' => (int) $_GET['id'] ] );Code language: PHP (php)
3. CSRF Token
session_start();
if ( empty( $_SESSION['csrf'] ) ) {
$_SESSION['csrf'] = bin2hex( random_bytes( 32 ) );
}
// 表單內
echo '<input type="hidden" name="csrf" value="' . e( $_SESSION['csrf'] ) . '">';
// 驗證 POST
if ( ! hash_equals( $_SESSION['csrf'], $_POST['csrf'] ?? '' ) ) {
http_response_code( 403 );
exit( 'Invalid CSRF token' );
}Code language: PHP (php)
4. 密碼雜湊
$hash = password_hash( $password, PASSWORD_DEFAULT );
if ( password_verify( $input_password, $hash ) ) {
// 登入成功
}Code language: PHP (php)
絕不用 MD5/SHA1 存密碼。
5. 檔案上傳
- 檢查副檔名與 MIME
- 重新命名檔案,不要信任使用者檔名
- 存到 Web 根目錄外,或禁止執行
6. 最小權限
資料庫帳號只給必要權限;正式環境關閉多餘 PHP 函式。
第 15 章:HTTP、路由與 MVC 概念
HTTP 方法
| 方法 | 用途 | 範例 |
|---|---|---|
| GET | 讀取 | 列表、詳情頁 |
| POST | 建立 / 提交表單 | 註冊、登入 |
| PUT/PATCH | 更新 | REST API |
| DELETE | 刪除 | REST API |
狀態碼
| 碼 | 意義 |
|---|---|
| 200 | 成功 |
| 302 | 重導向 |
| 400 | 客戶端錯誤 |
| 401 | 未授權 |
| 403 | 禁止 |
| 404 | 找不到 |
| 500 | 伺服器錯誤 |
http_response_code( 404 );
header( 'Location: /login' );
header( 'Content-Type: application/json; charset=utf-8' );Code language: JavaScript (javascript)
極簡路由(單檔示範)public/index.php:
<?php
require __DIR__ . '/../vendor/autoload.php';
$uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
$method = $_SERVER['REQUEST_METHOD'];
match ( [ $method, $uri ] ) {
[ 'GET', '/' ] => ( fn() => require '../views/home.php' )(),
[ 'GET', '/users' ] => ( fn() => ( new UserController() )->index() )(),
[ 'POST', '/login' ] => ( fn() => ( new AuthController() )->login() )(),
default => ( function () {
http_response_code( 404 );
echo 'Not Found';
} )(),
};Code language: HTML, XML (xml)
MVC 分工
flowchart LR
R[Router 路由] --> C[Controller 控制器]
C --> M[Model 模型 / 資料庫]
C --> V[View 視圖 / HTML]Code language: CSS (css)
| 層 | 職責 |
|---|---|
| Model | 資料與商業規則 |
| View | 呈現 HTML |
| Controller | 接收請求、呼叫 Model、選 View |
框架(Laravel、Symfony)幫你處理路由、ORM、樣板;底層仍是 PHP。
第 16 章:JSON API 與前後端分離
輸出 JSON
<?php
header( 'Content-Type: application/json; charset=utf-8' );
$data = [
'ok' => true,
'items' => [
[ 'id' => 1, 'title' => '第一則' ],
[ 'id' => 2, 'title' => '第二則' ],
],
];
echo json_encode( $data, JSON_UNESCAPED_UNICODE );Code language: HTML, XML (xml)
讀取 JSON body
$raw = file_get_contents( 'php://input' );
$body = json_decode( $raw, true );
if ( ! is_array( $body ) ) {
http_response_code( 400 );
echo json_encode( [ 'error' => 'Invalid JSON' ] );
exit;
}Code language: PHP (php)
REST 風格 CRUD
| 方法 | 路徑 | 動作 |
|---|---|---|
| GET | /api/todos | 列表 |
| GET | /api/todos/1 | 單筆 |
| POST | /api/todos | 新增 |
| PUT | /api/todos/1 | 更新 |
| DELETE | /api/todos/1 | 刪除 |
前端 React/Vue 用 fetch() 呼叫這些端點。
第 17 章:實戰迷你專案:待辦清單
整合所學:表單、PDO、Session、跳脫輸出。
資料表
CREATE TABLE todos (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
done TINYINT(1) NOT NULL DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Code language: PHP (php)
功能清單
1. `GET /` 顯示所有待辦
2. `POST /add` 新增(CSRF + 驗證)
3. `POST /toggle` 切換完成狀態
4. `POST /delete` 刪除
Code language: JavaScript (javascript)
目錄建議
todo-app/
public/
index.php # 唯一 Web 入口
src/
Database.php
TodoRepository.php
views/
list.php
config.php
composer.jsonCode language: PHP (php)
TodoRepository 核心邏輯
php
<?php
namespace App;
use PDO;
class TodoRepository {
public function __construct( private PDO $pdo ) {}
public function all(): array {
return $this->pdo->query( 'SELECT * FROM todos ORDER BY id DESC' )->fetchAll();
}
public function add( string $title ): void {
$stmt = $this->pdo->prepare( 'INSERT INTO todos (title) VALUES (:title)' );
$stmt->execute( [ 'title' => $title ] );
}
public function toggle( int $id ): void {
$stmt = $this->pdo->prepare( 'UPDATE todos SET done = NOT done WHERE id = :id' );
$stmt->execute( [ 'id' => $id ] );
}
public function delete( int $id ): void {
$stmt = $this->pdo->prepare( 'DELETE FROM todos WHERE id = :id' );
$stmt->execute( [ 'id' => $id ] );
}
}Code language: HTML, XML (xml)
完成此專案後,你已具備閱讀多數 PHP 專案骨架的能力!!
推薦資源
尾聲:學完 PHP 之後看 WordPress
WordPress 是用 PHP 寫成的 內容管理系統(CMS),全球數百萬網站使用。它不是 PHP 本身,而是建立在 PHP + MySQL 之上的應用程式。
若你之後要維護 Wiki、部落格、企業官網等 WordPress 專案,會發現:
| 你已學的 PHP | 在 WordPress 中的對應 |
|---|---|
include / 專案結構 | get_header()、get_template_part() |
$_GET / $_POST | 後台表單、REST API(仍建議用 WP API) |
| PDO / SQL | $wpdb、WP_Query、外掛的資料表 |
htmlspecialchars | esc_html()、esc_url() 等包裝函式 |
| Session | Cookie + WordPress 使用者系統 |
| Hooks 概念(事件) | add_action() / add_filter() |
| MVC 思維 | 模板(View)+ 主題 PHP + 外掛邏輯 |
建議順序:先把本篇 PHP 基礎與小專案練熟 → 再讀 WordPress Theme Handbook → 從改模板、加 functions.php Hook 開始,而不是直接改核心檔。
WordPress 主題開發本質上是:在 CMS 提供的掛勾與 API 上,用你已學會的 PHP 輸出 HTML、查資料、處理邏輯。PHP 底子穩,看任何 WordPress 主題都會輕鬆許多。

