PHP array_slice() 函數深度解析:參數詳解、分頁實作與進階技巧
array_slice() 是 PHP 陣列操作的核心函數,用於從陣列中提取一段連續元素。本文詳細說明語法參數、鍵名保留行為、分頁實作範例與常見陷阱。
函數語法與參數
array_slice(array $array, int $offset, int $length = null, bool $preserve_keys = false) : array
| 參數 | 說明 |
$array | 輸入陣列(必填) |
$offset | 起始位置:正數從前往後,負數從後往前(必填) |
$length | 提取長度:正數向後,負數從結尾往前計算,null 表示到結尾(選填) |
$preserve_keys | 保留鍵名:true 保留原鍵名,false 重新索引(預設 false) |
基本用法範例
<?php
$arr = [0, 1, 2, 3, 4];
var_dump(array_slice($arr, 0, 2)); // [0, 1] - 前兩個
var_dump(array_slice($arr, 2)); // [2, 3, 4] - 第3個到結尾
var_dump(array_slice($arr, -3, 2)); // [2, 3] - 倒數3個起取2個
var_dump(array_slice($arr, 1, -1)); // [1, 2, 3] - 第2個到倒數第2個
// 關聯陣列鍵名保留
$arr2 = ['a' => ['a','a','a'], 'b' => ['b','b','b']];
var_dump(array_slice($arr2, 0, 1, true)); // 保留鍵名 'a'
var_dump(array_slice($arr2, 0, 1, false)); // 重新索引 [0 => ...]
分頁實作完整範例
<?php
// 模擬資料庫查詢結果(二維陣列)
$records = [
['name' => 'name1', 'sex' => 'sex1', 'job' => 'job1'],
['name' => 'name2', 'sex' => 'sex2', 'job' => 'job2'],
['name' => 'name3', 'sex' => 'sex3', 'job' => 'job3'],
['name' => 'name4', 'sex' => 'sex4', 'job' => 'job4'],
['name' => 'name5', 'sex' => 'sex5', 'job' => 'job5'],
['name' => 'name6', 'sex' => 'sex6', 'job' => 'job6'],
['name' => 'name7', 'sex' => 'sex7', 'job' => 'job7'],
['name' => 'name8', 'sex' => 'sex8', 'job' => 'job8'],
['name' => 'name9', 'sex' => 'sex9', 'job' => 'job9'],
['name' => 'name10', 'sex' => 'sex10', 'job' => 'job10'],
['name' => 'name11', 'sex' => 'sex11', 'job' => 'job11'],
['name' => 'name12', 'sex' => 'sex12', 'job' => 'job12'],
];
// 分頁參數
$perPage = 3; // 每頁筆數
$total = count($records); // 總筆數
$totalPages = ceil($total / $perPage); // 總頁數
// 取得當前頁碼(預設第1頁)
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? (int)$_GET['page'] : 1;
$page = max(1, min($page, $totalPages)); // 限制範圍
// 計算陣列切片位置
$offset = ($page - 1) * $perPage;
$pageData = array_slice($records, $offset, $perPage, true); // 保留鍵名
// 輸出 HTML 表格
echo '<table border="1" cellpadding="5">';
echo '<tr><th>Name</th><th>Sex</th><th>Job</th></tr>';
foreach ($pageData as $row) {
echo '<tr>';
echo '<td>' . htmlspecialchars($row['name']) . '</td>';
echo '<td>' . htmlspecialchars($row['sex']) . '</td>';
echo '<td>' . htmlspecialchars($row['job']) . '</td>';
echo '</tr>';
}
echo '</table>';
// 分頁導航
echo '<div class="pagination">';
if ($page > 1) {
echo '<a href="?page=1">首頁</a> ';
echo '<a href="?page=' . ($page - 1) . '">上一頁</a> ';
}
if ($page < $totalPages) {
echo '<a href="?page=' . ($page + 1) . '">下一頁</a> ';
echo '<a href="?page=' . $totalPages . '">末頁</a> ';
}
echo " 第 {$page} / {$totalPages} 頁";
echo '</div>';
常見陷阱與注意事項
| 情況 | 行為 | 建議 |
| offset 超過陣列長度 | 回傳空陣列 | 預先檢查或配合 count() |
| length 為負數 | 從結尾往前計算長度 | 理解「倒數第 N 個」語意 |
| 關聯陣列未設 preserve_keys | 鍵名重新索引為 0,1,2... | 需保留鍵名時設為 true |
| 多維陣列 | 只切第一層,子陣列保持參考 | 深層切片需遞迴處理 |
效能比較
array_slice():C 層實作,效能極佳,適合大陣列
array_splice():會修改原陣列,若需保留原陣列請用 slice
- 手動
for 迴圈:效能較差,僅在需複雜邏輯時使用
進階技巧:陣列分塊處理
<?php
// 將大陣列分割為固定大小的區塊
function chunkArray(array $array, int $size, bool $preserveKeys = false) {
$chunks = [];
$offset = 0;
while ($offset < count($array)) {
$chunks[] = array_slice($array, $offset, $size, $preserveKeys);
$offset += $size;
}
return $chunks;
}
// 使用:批次處理 10000 筆資料,每批 500 筆
$chunks = chunkArray($bigData, 500);
foreach ($chunks as $batch) {
processBatch($batch); // 如:批次寫入資料庫、發送郵件
}
相關函數快速查詢
| 函數 | 用途 | 是否修改原陣列 |
array_slice | 提取片段(不修改原陣列) | 否 |
array_splice | 移除/替換片段(修改原陣列) | 是 |
array_chunk | 分割為固定大小區塊 | 否 |
array_splice | 提取並移除 | 是 |