<?php
$cards = ['A','2','3','4','5','6','7','8','9','10','J','Q','K'];
shuffle($cards); // 原地打亂,返回 bool
print_r($cards);
/* 示例輸出:
Array
(
[0] => Q
[1] => 3
[2] => 5
[3] => 2
[4] => 10
[5] => 9
[6] => K
[7] => 4
[8] => J
[9] => 6
[10] => 7
[11] => 8
[12] => A
)
*/
?>
特點:
• 修改原數組 (引用傳遞)
• 重新索引數字鍵 (0,1,2...)
• 字符串鍵保持不變
• 使用 Mersenne Twister 偽隨機數生成器
<?php // ❌ 錯誤:shuffle 返回 bool,不是新數組 $shuffled = shuffle($arr); // $shuffled = true // ✅ 正確:先複製再打亂 (保留原數組) $copy = $arr; shuffle($copy); // ❌ 錯誤:關聯數組字符串鍵會保留,但值順序打亂 $assoc = ['a'=>1, 'b'=>2, 'c'=>3]; shuffle($assoc); // 鍵 a,b,c 不變,值隨機重新分配 // 如需打亂鍵值對,需自定義 ?>
<?php
function shuffleAssoc(array $array): array {
$keys = array_keys($array);
shuffle($keys);
$result = [];
foreach ($keys as $key) {
$result[$key] = $array[$key];
}
return $result;
}
$assoc = ['id'=>1, 'name'=>'PHP', 'ver'=>8.2];
$shuffled = shuffleAssoc($assoc);
// 可能輸出: ['name'=>'PHP', 'id'=>1, 'ver'=>8.2] (鍵值對整體移動)
?>
<?php
function weightedShuffle(array $items, array $weights): array {
// $items = ['A','B','C']; $weights = [10, 30, 60];
$weighted = [];
foreach ($items as $i => $item) {
// 權重越大,複製份數越多
$weighted = array_merge($weighted, array_fill(0, $weights[$i], $item));
}
shuffle($weighted);
return $weighted; // 可能包含重複,按需去重或直接用於抽獎池
}
// 洗牌算法:Fisher-Yates (shuffle 內部實現)
function fisherYatesShuffle(array &$array): void {
for ($i = count($array) - 1; $i > 0; $i--) {
$j = mt_rand(0, $i);
[$array[$i], $array[$j]] = [$array[$j], $array[$i]];
}
}
?>
<?php
function seededShuffle(array $array, int $seed): array {
$copy = $array;
mt_srand($seed); // 設置種子
shuffle($copy);
mt_srand(); // 恢復隨機種子 (PHP 7.1+ 自動)
return $copy;
}
$data = range(1, 10);
$page1 = seededShuffle($data, 12345); // 固定種子,結果固定
$page2 = seededShuffle($data, 12346); // 不同種子,不同結果
// 同一用戶、同一會話使用固定種子,保證分頁順序一致
?>
| 方法 | 耗時 | 內存 | 特點 |
|---|---|---|---|
| shuffle() | ~120ms | 原地 | C 級實現,最快 |
| Fisher-Yates PHP 實現 | ~800ms | 原地 | 純 PHP,較慢 |
| array_rand + 重組 | ~200ms | 雙倍 | 不修改原數組 |
`shuffle()` 是 PHP 內置的高性能數組隨機排序函數,適用於數字索引數組原地打亂。關聯數組需自定義保持鍵值關係。進階場景涵蓋加權隨機、可復現種子、大數據性能優化。理解其行為邊界 (返回值、鍵名處理、偽隨機本質) 能避免常見 Bug。