sprintf() 與 printf() 是 PHP 核心字串格式化函數,源自 C 語言 printf 家族。兩者格式字串完全相同,唯一區別在於輸出方式。本文系統梳理格式佔位符、返回值差異、實戰場景與常見坑點。
| 特性 | sprintf() | printf() |
|---|---|---|
| 功能 | 返回格式化後的字串 | 直接輸出到標準輸出 |
| 返回值 | 格式化字串 (string) | 輸出字串長度 (int) |
| 典型用途 | 構建 SQL、生成文件名、組裝模板、日誌記錄 | CLI 腳本直接輸出、簡單頁面輸出 |
| 鏈式調用 | ✅ 支援 | ❌ 不支援 |
%[參數][寬度][.精度]類型 類型: % - 字面百分號 b - 二進制整數 c - ASCII 字符 d - 有符號十進制整數 e/E - 科學計數法 (小寫/大寫) f/F - 浮點數 (區域感知/不感知) g/G - 短數值格式 (自動選 f/e) o - 八進制整數 s - 字符串 u - 無符號十進制整數 x/X - 十六進制整數 (小寫/大寫)
| 標誌 | 含義 | 示例 |
|---|---|---|
- | 左對齊(預設右對齊) | %-10s |
+ | 正數顯示 + 號 | %+d → +5 |
空格 | 正數前加空格 | % d → 5 |
0 | 左側填 0(數值類型) | %05d → 00005 |
'<char> | 自定義填充字符 | %'*5s → ****a |
<?php
$nums = [21, 16.3287, 32.12329, -5.5, 0];
foreach ($nums as $n) {
// sprintf 返回字串,適合存儲/拼接
$formatted = sprintf('%0.2f', $n);
echo "$n → $formatted\n";
}
// 輸出:
// 21 → 21.00
// 16.3287 → 16.33
// 32.12329 → 32.12
// -5.5 → -5.50
// 0 → 0.00
解析 %0.2f:
% 起始0 填充字符(此處無寬度無效果).2 精度:小數點後 2 位f 類型:浮點數$orderNo = sprintf('ORD-%08d', $id); // ORD-00000123
$sql = sprintf("SELECT * FROM users WHERE status = '%s' AND created_at > '%s'",
$db->real_escape_string($status),
$db->real_escape_string($date)
);
function humanSize($bytes) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
while ($bytes >= 1024 && $i < 4) { $bytes /= 1024; $i++; }
return sprintf('%.2f %s', $bytes, $units[$i]);
}
printf("\033[32m[OK]\033[0m %s\n", 'Task completed'); // 綠色
printf("\033[31m[ERR]\033[0m %s\n", $error); // 紅色
| 坑點 | 後果 | 正確做法 |
|---|---|---|
printf 返回值被誤用為字串 | 得到長度數字而非格式化內容 | 需字串用 sprintf,需輸出用 printf |
| 參數數量不匹配 | Warning,佔位符原樣輸出 | 檢查佔位符與參數一一對應 |
| 多字節字符寬度計算錯 | %10s 中文顯示不對齊 | 用 mb_strwidth 計算視覺寬度後手動填充 |
| 浮點數精度陷阱 | sprintf('%.2f', 1.005) → 1.00(銀行家捨入) | 金額計算用 bcmath 或整數分存儲 |
| 格式字串注入 | 用戶輸入含 % 導致異常 | 格式字串硬編碼,用戶數據作參數傳入 |
// 100萬次循環
sprintf('%0.2f', $x); // ~0.18s
printf('%0.2f', $x); // ~0.22s (含 I/O)
number_format($x, 2); // ~0.12s (專用更快)
純數字格式化首選 number_format();需混合字串、多參數、復雜格式時用 sprintf();CLI 直接輸出用 printf()。
$data = ['張三', 25, '北京'];
echo vsprintf('姓名:%s,年齡:%d,城市:%s', $data);
// 姓名:張三,年齡:25,城市:北京
適合參數已在數組中(如資料庫查詢結果)的場景。