<?php
function dbConnect(
string $host = 'localhost',
string $user = 'root',
string $pass = '',
string $dbname = 'mydb',
int $port = 3306,
string $charset = 'utf8mb4'
): mysqli {
$mysqli = new mysqli($host, $user, $pass, $dbname, $port);
if ($mysqli->connect_errno) {
throw new Exception("DB連接失敗: {$mysqli->connect_error}");
}
$mysqli->set_charset($charset);
return $mysqli;
}
// 調用方式
$db = dbConnect(); // 全默認
$db = dbConnect('192.168.1.100'); // 僅指定 host
$db = dbConnect(pass: 'secret'); // PHP 8.0+ 命名參數
<?php
$db = dbConnect();
function queryUsers(mysqli $db): array
{
// 不推薦:global $db; // 破壞封裝,難以測試
// 推薦:參數傳遞或依賴注入容器
$res = $db->query('SELECT * FROM users');
return $res->fetch_all(MYSQLI_ASSOC);
}
<?php
function calculateTotal(array $items): float
{
$total = 0.0;
foreach ($items as $item) {
$total += ($item['price'] ?? 0) * ($item['qty'] ?? 0);
}
return round($total, 2);
}
// 可空類型
function findUser(int $id): ?array
{
// 返回數組或 null
}
<?php
class AppException extends Exception {}
class ValidationException extends AppException {}
class DatabaseException extends AppException {}
class NotFoundException extends AppException {}
// 統一處理器
set_exception_handler(function (Throwable $e) {
http_response_code($e instanceof ValidationException ? 400 : 500);
logError($e);
if (isApiRequest()) {
echo json_encode(['error' => $e->getMessage(), 'code' => $e->getCode()]);
} else {
include __DIR__ . '/templates/error.php';
}
});
function logError(Throwable $e): void
{
error_log(sprintf("[%s] %s in %s:%d\nTrace:\n%s",
date('c'), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString()
));
}
<?php
$pdo = new PDO('mysql:host=localhost;dbname=mydb;charset=utf8mb4', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // 真實預處理
<?php
// helpers.php
function h(string $str): string { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); }
function redirect(string $url, int $code = 302): never { header("Location: $url", true, $code); exit; }
function isAjax(): bool { return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'; }
function jsonResponse(array $data, int $code = 200): never { http_response_code($code); header('Content-Type: application/json'); echo json_encode($data, JSON_UNESCAPED_UNICODE); exit; }
function csrfToken(): string { return $_SESSION['csrf'] ??= bin2hex(random_bytes(32)); }
function verifyCsrf(string $token): bool { return hash_equals($_SESSION['csrf'] ?? '', $token); }
<?php
// config.php - 不直接返回數組,使用類封裝
class Config
{
private array $data = [];
public function __construct(string $envFile = __DIR__ . '/.env')
{
if (is_file($envFile)) {
foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
if (str_starts_with(trim($line), '#')) continue;
[$k, $v] = array_map('trim', explode('=', $line, 2));
$this->data[$k] = $v;
}
}
}
public function get(string $key, mixed $default = null): mixed
{
return $this->data[$key] ?? $_ENV[$key] ?? $_SERVER[$key] ?? $default;
}
}
$config = new Config();
$dbHost = $config->get('DB_HOST', 'localhost');
三日通核心知識體系:
進階學習路線:Composer 依賴管理 → PSR-4 自動加載 → MVC 框架 → ORM (Eloquent/Doctrine) → 單元測試 → Docker 容器化 → CI/CD 流水線 → 微服務架構。