PHP 15 個高效開發的小技巧
PHP 15 個高效開發的小技巧
在 PHP 開發中,你不需要依賴新框架也能顯著提升效率。真正有用的是那些能節省時間、減少重復工作的小技巧。本文將介紹一些簡單但強大的 PHP 技巧,幫助你編寫更簡潔、更健壯的代碼。
原文鏈接-PHP 15 個高效開發的小技巧
讓類型系統為你保駕護航
declare(strict_types=1);
function calculatePriceWithTax(float $price, float $taxRate): float {
return $price * (1 + $taxRate);
}
優勢:類型錯誤會立即顯現,而不是在后期才出現并難以追蹤。
使用空值合并和空安全操作符
簡化空值檢查:
// 空值合并
$username = $_GET['user'] ?? 'guest';
// 空安全操作符
$street = $order?->customer?->address?->street;
// 空值合并賦值
$config['timeout'] ??= 30;
使用 match 替代 switch
更簡潔的條件分支:
$statusText = match ($statusCode) {
200, 201 => '成功',
400 => '錯誤請求',
404 => '未找到',
500 => '服務器錯誤',
default => '未知狀態',
};
使用箭頭函數簡化回調
$prices = [12.5, 10.0, 3.5];
$pricesWithTax = array_map(fn($price) => round($price * 1.11, 2), $prices);
數組輔助函數
// 從用戶數組中提取郵箱
$emails = array_column($users, 'email');
// 按ID索引
$indexedById = array_column($users, null, 'id');
// 計算購物車總價
$total = array_reduce($cart,
fn($sum, $item) => $sum + $item['quantity'] * $item['price'],
0.0
);
使用 filter_var 驗證輸入
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
$ip = filter_var($_SERVER['REMOTE_ADDR'] ?? '', FILTER_VALIDATE_IP);
if (!$email) { /* 處理郵箱格式錯誤 */ }
安全的字符串處理
// 去除空白字符
$name = trim((string)($_POST['name'] ?? ''));
// 安全比較(防止時序攻擊)
if (hash_equals($knownToken, $providedToken)) {
// 驗證通過,繼續執行
}
使用 DateTimeImmutable 處理日期
$timezone = new DateTimeZone('Asia/Shanghai');
$now = new DateTimeImmutable('now', $timezone);
// 計算兩天后的上午9點
$deliveryTime = $now->modify('+2 days')->setTime(9, 0);
使用生成器處理大文件
/**
* 讀取CSV文件生成器
* @param string $filePath CSV文件路徑
* @return Generator 返回生成器,每次yield一行數據
* @throws RuntimeException 當文件無法打開時拋出異常
*/
function readCsvFile(string $filePath): Generator {
$handle = fopen($filePath, 'r');
if (!$handle) {
throw new RuntimeException("無法打開文件: $filePath");
}
try {
while (($row = fgetcsv($handle)) !== false) {
yield $row;
}
} finally {
fclose($handle);
}
}
// 使用示例
foreach (readCsvFile('/path/to/orders.csv') as [$id, $email, $amount]) {
// 處理每一行數據
}
使用 PDO 預處理語句和事務
// 數據庫連接配置
$dbConfig = [
'host' => 'localhost',
'dbname' => 'shop',
'charset' => 'utf8mb4',
'username' => 'username',
'password' => 'password'
];
// 創建PDO實例
$dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['dbname']};charset={$dbConfig['charset']}";
$pdo = new PDO($dsn, $dbConfig['username'], $dbConfig['password'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 設置錯誤模式為異常
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 設置默認獲取模式為關聯數組
PDO::ATTR_EMULATE_PREPARES => false, // 禁用預處理語句的模擬
]);
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare('INSERT INTO orders (email, amount) VALUES (:email, :amount)');
foreach ($orders as $order) {
$stmt->execute([
':email' => $order['email'],
':amount' => $order['amount']
]);
}
$pdo->commit();
} catch (Throwable $e) {
$pdo->rollBack();
throw $e;
}
使用 Composer 自動加載
在 composer.json 中配置:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
運行 composer dump-autoload 使配置生效。
使用屬性(PHP 8+)
#[
Attribute
]
class Route {
public function __construct(
public string $method,
public string $path
) {}
}
#[Route('GET', '/health-check')]
function healthCheck(): array {
return ['status' => '成功'];
}
使用 SPL 迭代器
$dir = new RecursiveDirectoryIterator(__DIR__ . '/logs');
$iterator = new RecursiveIteratorIterator($dir);
foreach ($iterator as $path => $fileInfo) {
if ($fileInfo->isFile() && str_ends_with($path, '.log')) {
// 處理日志文件內容
}
}
使用特定的異常類型
/**
* 訂單未找到異常
*/
class OrderNotFoundException extends RuntimeException {}
function getOrder(PDO $db, int $orderId): array {
$stmt = $db->prepare('SELECT * FROM orders WHERE id = :id');
$stmt->execute([':id' => $orderId]);
$row = $stmt->fetch();
if (!$row) {
throw new OrderNotFoundException("Order with ID $orderId not found");
}
return $row;
}
創建命令行腳本
#!/usr/bin/env php
<?php
declare(strict_types=1);
$options = getopt('', ['path:']);
$filePath = $options['path'] ?? 'input.csv';
foreach (readCsvFile($filePath) as $row) {
// 處理每一行
}
實戰示例:CSV 導入數據庫
$db->beginTransaction();
$stmt = $db->prepare('INSERT INTO orders (id, email, amount, created_at) VALUES (:id, :email, :amount, :created_at)');
$batch = 0;
foreach (readCsvFile('orders.csv') as $lineNumber => $row) {
if ($lineNumber === 0) continue; // 跳過CSV文件的標題行
[$id, $email, $amount, $createdAt] = $row;
// 數據驗證
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
$amount = is_numeric($amount) ? (float)$amount : null;
if (!$email || $amount === null) {
// 記錄無效數據行
error_log("第 {$lineNumber} 行數據無效: " . json_encode($row));
continue;
}
// 日期時間格式化
$timezone = new DateTimeZone('Asia/Shanghai');
$createdAt = (new DateTimeImmutable($createdAt, $timezone))->format('Y-m-d H:i:s');
// 執行數據庫插入
$stmt->execute([
':id' => (int)$id,
':email' => $email,
':amount' => $amount,
':created_at' => $createdAt,
]);
// 每處理1000條記錄提交一次事務
if ((++$batch % 1000) === 0) {
$db->commit();
$db->beginTransaction();
}
}
$db->commit();
總結
這些技巧可以幫助你:
- 編寫更健壯的代碼
- 提高開發效率
- 處理大數據量時保持低內存占用
- 使代碼更易于維護
選擇幾個最符合你工作流程的技巧開始使用,逐步將它們融入你的日常開發中。

浙公網安備 33010602011771號