首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 進階實用函式精選:sys_getloadavg、pack、cal_days_in_month 等 10 個隱藏寶石

     編輯:PHP 相關知識

PHP 內建超過 1000 個函式,許多強大卻鮮為人知的「隱藏寶石」能解決特定棘手問題。本文精選 10 個高實用價值、低知名度的函式,附完整範例、適用場景與注意事項,擴展你的 PHP 工具箱。

1. sys_getloadavg() - 系統負載監控 (Linux/Unix 限定)

<?php
// 回傳陣列 [1分鐘, 5分鐘, 15分鐘] 平均負載
$load = sys_getloadavg(); 
// 例: [0.45, 0.32, 0.28]

// 實戰:高負載時拒絕請求,保護系統穩定
if ($load[0] > 10.0) { // 1分鐘負載超過 CPU 核心數 10 倍
    http_response_code(503);
    header('Retry-After: 30');
    die('系統過載,請稍後再試');
}

// 注意:Windows 環境回傳 false,需判斷
if ($load === false) {
    // Windows 替代方案:wmic 或 performance counters
}
?>

2. pack() - 二進位封裝 (節省儲存空間)

<?php
// md5() 回傳 32 字元十六進位字串 (128 bits)
$hex = md5('secret'); // "5ebe2294ecd0e0f08eab7690d2a6ee69"

// pack('H*', ...) 將十六進位轉為 16 位元組二進位字串
$bin = pack('H*', $hex); // 長度 16 bytes,節省 50% 空間

// 資料庫儲存:BINARY(16) 欄位而非 CHAR(32)
// 反向解包
$hexRestored = unpack('H*', $bin)[1]; // 還原十六進位

// 其他常用格式
pack('N', 123456);     // 32-bit 無號大端序 (網路位元組序)
pack('V', 123456);     // 32-bit 無號小端序
pack('H*', 'ff00aa');  // 十六進位字串
pack('C*', 255,0,170); // 位元組陣列
?>

3. cal_days_in_month() - 取得月份天數 (支援多曆法)

<?php
// 格里曆 (西曆)
echo cal_days_in_month(CAL_GREGORIAN, 2, 2024); // 29 (閏年)
echo cal_days_in_month(CAL_GREGORIAN, 2, 2023); // 28

// 猶太曆、法國共和曆等
echo cal_days_in_month(CAL_JEWISH, 7, 5784);

// 實戰:產生月曆
function renderCalendar(int $year, int $month): string {
    $days = cal_days_in_month(CAL_GREGORIAN, $month, $year);
    $firstDay = (int)date('w', strtotime("$year-$month-01")); // 0=週日
    $html = "<table><tr><th>日</th><th>一</th>...<th>六</th></tr><tr>";
    $html .= str_repeat("<td></td>", $firstDay);
    for ($d = 1; $d <= $days; $d++) {
        $html .= "<td>$d</td>";
        if (($firstDay + $d) % 7 === 0) $html .= "</tr><tr>";
    }
    return $html . "</tr></table>";
}
?>

4. _() / _e() - 國際化 (i18n) 翻譯函式 (Gettext)

<?php
// 設定語言環境
putenv('LC_ALL=zh_TW.utf8');
setlocale(LC_ALL, 'zh_TW.utf8');
bindtextdomain('myapp', __DIR__ . '/locale');
textdomain('myapp');

// _() 回傳翻譯字串
$msg = _("Welcome to our website");

// _e() 直接輸出 (echo _())
_e("Welcome to our website"); 

// 進階:複數形式 ngettext()
printf(ngettext("%d file", "%d files", $count), $count);

// .po 檔案範例
/*
msgid "Welcome to our website"
msgstr "歡迎來到我們的網站"

msgid "%d file"
msgid_plural "%d files"
msgstr[0] "%d 個檔案"
msgstr[1] "%d 個檔案"
*/
?>

5. get_browser() - 瀏覽器能力偵測

<?php
// 需 php_browscap.ini (從 https://browscap.org/ 下載放入 PHP 目錄)
// php.ini: browscap = /path/to/php_browscap.ini

$browser = get_browser(null, true); // true = 回傳陣列而非物件
/*
Array (
    [browser_name_regex] => ^mozilla/5\.0 \(.*windows nt 10\.0.*\) applewebkit/.* \(khtml, like gecko\) chrome/.* safari/.*$
    [browser_name_pattern] => Mozilla/5.0 (*Windows NT 10.0*) AppleWebKit/* (KHTML, like Gecko) Chrome/* Safari/*
    [parent] => Chrome 120.0
    [platform] => Win10
    [browser] => Chrome
    [version] => 120.0
    [majorver] => 120
    [minorver] => 0
    [cssversion] => 3
    [frames] => 1
    [iframes] => 1
    [tables] => 1
    [cookies] => 1
    [javascript] => 1
    [vbscript] => 
    [activexcontrols] => 
    [isbanned] => 
    [ismobiledevice] => 
    [istablet] => 
    [issyndicationreader] => 
    [crawler] => 
    ...
)
*/

// 實戰:針對舊瀏覽器提供 Polyfill
if (isset($browser['javascript']) && !$browser['javascript']) {
    echo '<script src="polyfill.min.js"></script>';
}

// 注意:無法偵測使用者「關閉 JS」的情況,只能判斷瀏覽器「能力」
?>

6. debug_print_backtrace() - 除錯呼叫堆疊

<?php
function a() { b(); }
function b() { c(); }
function c() { 
    echo "--- Backtrace ---\n";
    debug_print_backtrace(); 
    echo "\n-----------------\n";
}
a();

/*
輸出:
--- Backtrace ---
#0  c() called at [/path/file.php:2]
#1  b() called at [/path/file.php:1]
#2  a() called at [/path/file.php:5]
-----------------
*/

// 進階:取得陣列而非輸出
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // 忽略參數節省記憶體
foreach ($trace as $frame) {
    echo "{$frame['function']}() in {$frame['file']}:{$frame['line']}\n";
}
?>

7. metaphone() - 英文單字發音編碼 (相似發音匹配)

<?php
// 相同發音 -> 相同 Metaphone 編碼
echo metaphone("phone");    // FN
echo metaphone("fone");     // FN
echo metaphone("phonetic"); // FNTK

// 實戰:模糊搜尋、姓名匹配
$names = ['Smith', 'Smyth', 'Smythe', 'Johnson', 'Jonson'];
$target = 'Smith';
$targetCode = metaphone($target);

foreach ($names as $name) {
    if (metaphone($name) === $targetCode) {
        echo "相似發音: $name\n"; // Smith, Smyth, Smythe
    }
}

// 注意:僅適用英文,中文無效
?>

8. natsort() - 自然排序 (人類直覺順序)

<?php
$items = ['img1.png', 'img10.png', 'img2.png', 'img20.png', 'img3.png'];

// 一般排序 (字典序)
sort($items);
// ['img1.png', 'img10.png', 'img2.png', 'img20.png', 'img3.png'] ❌

// 自然排序
natsort($items);
// ['img1.png', 'img2.png', 'img3.png', 'img10.png', 'img20.png'] ✅

// 關聯陣列保持鍵值
$files = [
    'a' => 'file10.txt',
    'b' => 'file2.txt',
    'c' => 'file1.txt'
];
natsort($files);
// ['c'=>'file1.txt', 'b'=>'file2.txt', 'a'=>'file10.txt']

// 反向自然排序
$items = ['v1.2', 'v1.10', 'v1.1'];
natrsort($items); // ['v1.10', 'v1.2', 'v1.1']
?>

9. levenshtein() - 編輯距離 (拼字檢查、模糊匹配)

<?php
// 計算將字串 A 轉為 B 所需最少編輯操作 (插入/刪除/替換)
echo levenshtein('kitten', 'sitting'); // 3 (k→s, e→i, +g)

// 實戰:搜尋建議 "Did you mean...?"
$dict = ['php', 'javascript', 'python', 'java', 'go', 'rust'];
$input = 'phpp'; // 使用者輸入錯誤

$best = $dict[0];
$minDist = levenshtein($input, $best);

foreach ($dict as $word) {
    $dist = levenshtein($input, $word);
    if ($dist < $minDist) {
        $minDist = $dist;
        $best = $word;
    }
}
echo "Did you mean '$best'? (distance: $minDist)"; // Did you mean 'php'? (distance: 1)

// 自訂成本 (插入、替換、刪除權重不同)
echo levenshtein('a', 'b', 1, 2, 1); // 替換成本 2
?>

10. glob() - 路徑模式匹配 (取代 opendir/readdir)

<?php
// 尋找所有 .php 檔案
foreach (glob("*.php") as $file) {
    echo "$file\n";
}

// 遞迴尋找 (需 PHP 5.5+ GLOB_BRACE)
$phpFiles = glob("**/*.php", GLOB_BRACE); // 需支援 ** 模式或用 RecursiveDirectoryIterator

// 更強大的替代:GlobIterator
$it = new GlobIterator("*.php");
foreach ($it as $file) {
    echo $file->getFilename() . " (" . $file->getSize() . " bytes)\n";
}

// 常用模式
glob("*.{php,html,css,js}", GLOB_BRACE);      // 多副檔名
glob("../data/*.csv");                        // 相對路徑
glob("/var/log/*.log", GLOB_NOSORT);          // 不排序 (大量檔案較快)
glob("*", GLOB_ONLYDIR);                      // 僅目錄
glob("*", GLOB_MARK);                         // 目錄名加斜線

// 注意:Windows 路徑分隔符為 \,glob() 接受 / 並自動轉換
?>

總結比較表

函式核心用途關鍵限制替代/補充
sys_getloadavg系統負載監控僅 Linux/UnixWindows: wmic / performance counters
pack/unpack二進位序列化格式字串複雜MessagePack, Protocol Buffers
cal_days_in_month月份天數需 calendar 擴充 (通常內建)date('t') 簡易版
_()/_e()Gettext 翻譯需 .po/.mo 檔案、locale 設定Symfony Translation, Laravel __()
get_browser瀏覽器能力需 browscap.ini、無法偵測使用者設定User-Agent 解析庫 (UAParser)
debug_print_backtrace除錯堆疊僅輸出,不回傳debug_backtrace() 回傳陣列
metaphone英文發音編碼僅英文soundex(), Double Metaphone
natsort自然排序修改原陣列、不支援多維usort + strnatcmp
levenshtein編輯距離長字串 O(n*m) 慢、>255 字元回傳 -1similar_text(), 外部演算法庫
glob檔案模式匹配不支援遞迴 ** (需迭代器)RecursiveDirectoryIterator, Finder

避坑指南

  • sys_getloadavg() 在 Windows 回傳 false,必須判斷,否則 $load[0] 會報錯。
  • pack('H*', ...) 輸入長度必須為偶數 (每 2 字元 = 1 byte),否則補 0 或報警。
  • get_browser() 預設回傳物件,陣列操作需傳 true 參數。
  • levenshtein() 字串長度超過 255 字元會直接回傳 -1,長字串需分段或用其他演算法。
  • glob() 回傳陣列包含完整路徑 (相對或絕對),basename() 取純檔名。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved