項目中常遇到「從固定備選池隨機抽取一項」的需求:側邊欄輪播廣告語、文章底部隨機推薦、驗證碼字符生成等。PHP 提供了多種實現路徑,本文對比三種主流寫法,並給出擴展性最佳實踐。
$options = [
'廣告語 1:全年無休,服務至上',
'廣告語 2:品質保證,值得信賴',
'廣告語 3:新客首單立減 20 元',
'廣告語 4:會員專享雙倍積分',
'廣告語 5:滿額包郵,全場無門檻'
];
$index = rand(0, count($options) - 1);
echo $options[$index];
優點: 直觀易懂,適合極簡場景。
缺點: 硬編碼數組,維護成本高;rand() 隨機質量一般(PHP 7.1+ 已為 mt_rand() 別名)。
array_rand(array $array, int $num = 1): int|string|array 直接返回隨機鍵名,支援一次取多個且不重複。
$ads = [
'slogan_1' => '極速送達,當日達',
'slogan_2' => '正品行貨,假一賠十',
'slogan_3' => '新人註冊送 100 元券包',
'slogan_4' => '限時秒殺,低至 1 折起',
'slogan_5' => '滿 199 減 50,上不封頂'
];
// 取 1 個鍵名
$key = array_rand($ads);
echo $ads[$key]; // 輸出對應值
// 進階:一次取 3 個不重複鍵名
$keys = array_rand($ads, 3);
foreach ($keys as $k) {
echo $ads[$k] . '<br>';
}
優點: 代碼簡潔、語義明確、自動去重、支援關聯數組保留鍵名。
注意: PHP 7.1 起不再內部打亂數組,若需打亂順序可配合 shuffle()。
實際專案中,廣告語、推薦語等內容頻繁變動,硬編碼在代碼裡是大忌。建議:
ad_slogans(id, content, weight, status, created_at),weight 權重字段支援加權隨機。config/slogans.php 返回純數組,部署時由運營同學維護,無需改動代碼。// 假設已查出 $rows = [['content'=>'...', 'weight'=>10], ...]
$totalWeight = array_sum(array_column($rows, 'weight'));
$rand = mt_rand(1, $totalWeight);
$accum = 0;
foreach ($rows as $row) {
$accum += $row['weight'];
if ($rand <= $accum) {
echo $row['content'];
break;
}
}
count($arr)-1 為 -1 導致 rand(0,-1) 拋錯。永遠先判斷 empty($arr)。array_values($arr) 重建索引,或直接用 array_rand() 返回鍵名。random_int() 或 openssl_random_pseudo_bytes(),禁用 rand/mt_rand/array_rand。| 方法 | 適用場景 | 代碼量 | 隨機質量 | 維護性 |
|---|---|---|---|---|
| rand + 索引 | 臨時腳本、數據極少且固定 | 低 | 一般 | 差 |
| array_rand() | 常規業務、需取多值、關聯數組 | 極低 | 良好 | 中 |
| 資料庫/配置+加權 | 正式專案、內容常變、需運營自主控制 | 中 | 可控 | 優 |
「隨機取值」看似簡單,卻藏著工程化演進的縮影:從硬編碼到配置分離,從均勻隨機到加權分佈,再到緩存優化與安全隨機。根據項目階段選擇合適層級的方案,才是成熟開發者的標誌。