十大開發經驗
- 關閉 register_globals:從學習第一天就設為 Off,防止變數注入
- 開啟錯誤回報:開發環境
error_reporting(E_ALL)、display_errors=On
- 先查手冊再問人:PHP 官方文件極完整,善用範例、註釋、版本差異說明
- 善用搜尋引擎:錯誤訊息貼上 Google/Stack Overflow,多半已有解
- 切忌好大喜功:剛學會就想寫論壇/CMS,先累積小專案經驗
- HTML 基礎要扎實:語意標籤、表單、無障礙、SEO 基礎
- 樂於分享、善於提問:回答新手問題能倒逼自己釐清概念
- 動手實作勝過空想:思考後立刻寫代碼驗證
- 定期重構回顧:一週後重讀自己的代碼,尋找改進點
- 閱讀他人優秀代碼:GitHub 熱門專案、框架核心、設計模式實作
效能與寫法優化技巧
1. 善用參考傳遞
function processLargeArray(array &$data): void { // 避免複製大陣列
// ...
}
2. 三元運算子簡化條件賦值
// 冗長
if ($data[$i]['nickname']) $nick = $data[$i]['nickname'];
else $nick = $data[$i]['ip'];
// 簡潔
$nick = $data[$i]['nickname'] ?: $data[$i]['ip'];
// PHP 7+ null 合併
$nick = $data[$i]['nickname'] ?? $data[$i]['ip'];
3. 合併巢狀條件
// 多層 if
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (!empty($allowed)) {
if (!in_array($ext, $allowed)) { die('不允許的副檔名'); }
}
// 合併
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if ($allowed !== '' && !in_array($ext, $allowed)) { die('不允許的副檔名'); }
4. 避免在迴圈中查詢資料庫 (N+1 問題)
// 錯誤
foreach ($users as $u) {
$posts = $pdo->query("SELECT * FROM posts WHERE user_id={$u['id']}")->fetchAll();
}
// 正確:單次查詢 + 陣列分組
$posts = $pdo->query('SELECT * FROM posts WHERE user_id IN (' . implode(',', array_column($users,'id')) . ')')->fetchAll();
$byUser = [];
foreach ($posts as $p) $byUser[$p['user_id']][] = $p;
5. 使用預備語句 + 參數綁定
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
$stmt->execute([$email, 'active']);
6. 適度快取
- OPcache (必開)
- 資料庫查詢結果快取 (Redis/Memcached)
- 靜態頁面快取 (Varnish/Nginx fastcgi_cache)
7. 只選需要的欄位
// 避免 SELECT *
$stmt = $pdo->query('SELECT id, name, email FROM users');
8. 索引優化
- WHERE、JOIN、ORDER BY 欄位建立索引
- 複合索引遵循最左前綴原則
- 定期
ANALYZE TABLE、觀察 EXPLAIN
現代開發流程建議
- 版本控制:Git + GitHub/GitLab
- 依賴管理:Composer + Packagist
- 編碼標準:PSR-12 + PHP_CodeSniffer + PHP-CS-Fixer
- 靜態分析:PHPStan Level 5+ / Psalm
- 測試:PHPUnit + Pest、測試覆蓋率 > 80%
- CI/CD:GitHub Actions / GitLab CI 自動測試、部署
- 容器化:Docker + docker-compose 本地開發環境一致性