掌握 PHP 語法只是起點,寫出可維護、安全、高效能的代碼需要遵循成熟的工程實踐。本文整理十大核心技巧,附現代框架視角補充。
採用 index.php 單一入口,透過路由分發:
<?php
// public/index.php
require_once __DIR__ . '/../vendor/autoload.php';
$app = require_once __DIR__ . '/../bootstrap/app.php';
$app->run();
?>
Nginx/Apache 重寫規則將所有請求導向 index.php。優點:集中安全檢查、啟動流程、統一異常處理、支援 RESTful URL。
<?php
// 取得輸入 (GET/POST/JSON 統一)
$input = array_merge($_GET, $_POST, (array)json_decode(file_get_contents('php://input'), true));
// 白名單過濾
$allowed = ['name', 'email', 'age'];
$data = array_intersect_key($input, array_flip($allowed));
// 驗證 (建議使用 respect/validation、symfony/validator)
if (empty($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Email 格式錯誤');
}
?>
var_dump():基礎輸出,輸出型別與長度。debug_zval_dump():顯示參考計數。dump($var)) —— 彩色、可摺疊、支援 Lazy Loading、整合 Laravel/Twig。採用 MVC 或 ADR (Action-Domain-Responder) 架構:
範例結構:
src/
├── Controller/ # 薄控制器
├── Service/ # 業務邏輯
├── Repository/ # 資料存取
├── Entity/ # 領域模型
└── View/ # 模板或 API Resource
使用 .env (vlucas/phpdotenv) + 設定陣列/物件:
<?php
// config/app.php
return [
'debug' => env('APP_DEBUG', false),
'db' => [
'host' => env('DB_HOST', '127.0.0.1'),
'name' => env('DB_NAME'),
'user' => env('DB_USER'),
'pass' => env('DB_PASS'),
],
'cache' => env('CACHE_DRIVER', 'redis'),
];
?>
禁止在代碼中硬編碼敏感資訊,不要使用 global 關鍵字。
<?php
// public/index.php
define('APP_STARTED', true);
// src/Service/UserService.php
if (!defined('APP_STARTED')) {
http_response_code(403);
exit('Direct access forbidden');
}
?>
現代框架由路由/中介層處理,無需手動定義常數。
使用 PDO + Repository 模式:
<?php
class UserRepository {
private PDO $pdo;
public function __construct(PDO $pdo) { $this->pdo = $pdo; }
public function findById(int $id): ?array {
$stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
return $stmt->fetch() ?: null;
}
public function create(array $data): int {
$sql = 'INSERT INTO users (name, email) VALUES (?, ?)';
$this->pdo->prepare($sql)->execute([$data['name'], $data['email']]);
return (int)$this->pdo->lastInsertId();
}
}
?>
優點:可測試 (Mock PDO)、SQL 集中管理、易於切換資料庫/ORM。
控制器僅負責 HTTP 協議轉換:
<?php
class UserController {
public function __construct(private UserService $service) {}
public function store(Request $request): JsonResponse {
$data = $request->validate(['name' => 'required', 'email' => 'required|email']);
$user = $this->service->createUser($data);
return response()->json($user, 201);
}
}
?>
$stmt->execute([$params])。<?php
class Database {
private static ?PDO $instance = null;
private function __construct() { /* PDO 初始化 */ }
public static function getInstance(): PDO {
if (self::$instance === null) {
self::$instance = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
}
return self::$instance;
}
// 禁止克隆與反序列化
private function __clone() {}
public function __wakeup() { throw new Exception("Cannot unserialize"); }
}
?>
適用場景:資料庫連線、配置物件、快取客戶端、日誌器。注意:單例增加全域狀態,單元測試需提供重置方法或改用依賴注入容器管理生命週期。
declare(strict_types=1); + 型別提示。composer require --dev phpstan/phpstan 並納入 CI。composer require --dev friendsofphp/php-cs-fixer 統一風格。