接續上篇,本文涵蓋 SQL 抽象封裝、靜態快取、Session 資料庫化、Base 標籤、錯誤報告策略、32/64 位平台差異、set_time_limit 陷阱、擴充套件善用、MVC 框架選型、phpbench 基準測試、Index 設計、$_REQUEST 使用、var_dump 調試、Smarty 模板引擎、Config 集中管理、存取控制、資料庫類封裝、單一職責分層、SQL 審計、單例模式、重導向方式、UA/OS 偵測、MIME 對照表、Excel 匯出等實戰技巧。
class DB {
public function insert($table, array $data) {
$fields = implode(',', array_keys($data));
$placeholders = ':' . implode(',:', array_keys($data));
$sql = "INSERT INTO $table ($fields) VALUES ($placeholders)";
$stmt = $this->pdo->prepare($sql);
foreach ($data as $k => $v) $stmt->bindValue(":$k", $v);
return $stmt->execute();
}
public function update($table, array $data, $where, $whereArgs) { ... }
public function select($table, $fields, $where, $args) { ... }
}
// 使用
$db->insert('users', ['name'=>$name, 'email'=>$email, 'phone'=>$phone]);
優點:自動參數繫結防注入、語法錯誤編譯期發現、易擴展分頁/軟刪除/審計。
$cacheFile = CACHE_DIR . '/article_' . $id . '.html';
if (file_exists($cacheFile) && time() - filemtime($cacheFile) < 3600) {
readfile($cacheFile); exit;
}
ob_start();
// ... 複雜渲染邏輯 ...
$html = ob_get_clean();
file_put_contents($cacheFile, $html);
echo $html;
優點:繞過 PHP 執行、資料庫查詢、模板解析,極致效能。
// 自訂 Session Handler (Redis 範例)
class RedisSessionHandler implements SessionHandlerInterface {
private $redis;
public function __construct() { $this->redis = new Redis(); $this->redis->connect('127.0.0.1'); }
public function read($id) { return $this->redis->get("sess:$id") ?: ''; }
public function write($id, $data) { return $this->redis->setex("sess:$id", 3600, $data); }
public function destroy($id) { return $this->redis->del("sess:$id"); }
public function gc($maxlifetime) { return true; } // Redis 自動過期
// open/close 空實作
}
session_set_save_handler(new RedisSessionHandler(), true);
session_start();
優點:多伺服器共享 Session、重啟不丟失、可實作踢下線/單裝置登入。
// 差
$GLOBALS['config']['db_host'] = '...';
// 好
class Config { const DB_HOST = '...'; }
function config($key) { static $cfg; return $cfg[$key] ?? null; }
class Service { private $db; public function __construct(DB $db) { $this->db = $db; } }
<head><base href="https://cdn.example.com/assets/"></head> <img src="logo.png"> <!-- 實際請求 https://cdn.example.com/assets/logo.png --> <a href="page.html"> <!-- 實際跳轉 https://cdn.example.com/assets/page.html -->
解決多層級目錄下共用導航/資源路徑不一致問題。
ini_set('display_errors', ENV === 'dev' ? 1 : 0);
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
// 生產環境記錄至日誌
ini_set('log_errors', 1);
ini_set('error_log', '/var/log/php/error.log');
// 64 位
strtotime('0000-00-00') // -62170005200
// 32 位
strtotime('0000-00-00') // false
// 解法:統一用 DateTime 物件
$dt = new DateTime('2000-01-01');
echo $dt->getTimestamp(); // 跨平台一致
set_time_limit(30) 僅限制 PHP 內部 CPU 時間,**不包含**資料庫查詢、cURL、檔案 I/O、sleep、shell_exec 等系統呼叫時間。長跑任務應用獨立 Worker + 超時監控。
CodeIgniter、Laravel、Symfony、Yii、ThinkPHP、Phalcon 等框架提供:路由、DI 容器、ORM、遷移、驗證、快取、隊列、測試工具鏈,強制關注點分離,團隊協作效率指數級提升。
phpbench.com 提供語法層面微觀效能對比(如 isset vs array_key_exists、foreach vs for),避免「感覺快」的主觀優化。
// 單一入口
$page = $_GET['page'] ?? 'home';
$allowed = ['home','about','contact','admin'];
if (!in_array($page, $allowed)) $page = 'home';
include "pages/{$page}.php";
便於權限控制、日誌、重寫規則、CSRF 保護集中處理。
$action = $_REQUEST['action'] ?? 'default';
注意:$_REQUEST 合併順序受 request_order (GP/C) 影響,安全敏感欄位(如密碼、Token)建議顯式指定 $_POST 或 $_GET。
var_dump($var); // 類型、長度、結構一目瞭然 // Xdebug 開啟後自動美化、顏色、深度限制
{* template.tpl *}
<h1>{$title|escape}</h1>
<ul>{foreach $items as $item}<li>{$item.name}</li>{/foreach}</ul>
Smarty 編譯快取、模板繼承、沙箱安全,適合設計師與程式師分工。
// config.php return [ 'db' => ['host'=>'...', 'user'=>'...', 'pass'=>'...', 'name'=>'...'], 'app' => ['name'=>'MyApp', 'url'=>'https://...', 'timezone'=>'Asia/Taipei'], ]; // 使用 $config = require __DIR__ . '/config.php'; $dbHost = $config['db']['host'];
// index.php
define('APP_ENTRY', true);
// other.php
if (!defined('APP_ENTRY')) die('Access Denied');
class DB {
public function query($sql, $params = []) {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
if ($this->debug) $this->log($sql, $params, $stmt->rowCount());
return $stmt;
}
}
// index.php
$action = $_GET['action'] ?? 'list';
require_once 'Message.php';
$msg = new Message();
switch ($action) {
case 'list': $msg->list(); break;
case 'send': $msg->send($_POST); break;
}
SELECT pm.*, u.username AS sender_name FROM private_msg pm JOIN users u ON u.id = pm.sender_id WHERE pm.receiver_id = :uid AND pm.sender_purge = 0 ORDER BY pm.sent_at DESC
class Logger {
private static $inst;
private function __construct() {}
public static function get() {
if (!self::$inst) self::$inst = new self();
return self::$inst;
}
}
// 1. HTTP Header (推薦)
header('Location: /target.php'); exit;
// 2. JS 重導
echo "";
// 3. Meta Refresh
echo '';
手寫正則維護成本極高,推薦 composer require ua-parser/uaparser。
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="export.xls"');
echo "欄1\t欄2\n值1\t值2\n";
現代專案建議用 PhpSpreadsheet 產出真正的 .xlsx。
至此 50 條技巧完整呈現。建議團隊建立《PHP 開發規範清單》並納入 Code Review 標準,持續沉澱最佳實踐。