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

PHP 陣列指標操作函數完整指南:current、next、prev、end、reset、each、key 實戰

     編輯:PHP 綜合知識

PHP 陣列內部維護一個「指標」指向當前元素。掌握指標操作函數,能高效實作迭代、倒序、特定位置存取等邏輯,尤其在處理大型陣列、避免複製、實作自定義迭代器時極具價值。本文系統整理所有指標函數、參數、回傳值、常見陷阱與實戰範例。

核心指標函數速查表

函數原型動作回傳值指標移動
currentcurrent(array|object $array): mixed取得當前元素值當前值 / false (指標超出範圍)否
nextnext(array|object $array): mixed指標前進一格,取得下一個值下一個值 / false (已是最後)是 (+1)
prevprev(array|object $array): mixed指標後退一格,取得上一個值上一個值 / false (已是第一個)是 (-1)
endend(array|object $array): mixed指標移至最後一個元素最後值 / false (空陣列)是 (至末尾)
resetreset(array|object $array): mixed指標重置至第一個元素第一個值 / false (空陣列)是 (至開頭)
eacheach(array|object $array): array|false取得當前鍵值對,指標前進[key, value, 0=key, 1=value] / false是 (+1)
keykey(array|object $array): mixed取得當前元素鍵名鍵名 (int/string) / null (指標超出)否

基本操作範例

<?php
$transport = ['foot', 'bike', 'car', 'plane'];

$mode = current($transport); // 'foot' (指標在 0)
$mode = next($transport);    // 'bike' (指標移至 1)
$mode = next($transport);    // 'car'  (指標移至 2)
$mode = prev($transport);    // 'bike' (指標退回 1)
$mode = end($transport);     // 'plane' (指標跳至 3)
$mode = reset($transport);   // 'foot'  (指標回到 0)

// each() 回傳鍵值對陣列
reset($transport);
while (($pair = each($transport)) !== false) {
    // $pair = [1 => 'foot', 'value' => 'foot', 0 => 0, 'key' => 0]
    echo "Key: {$pair['key']}, Value: {$pair['value']}\n";
}
// 輸出:
// Key: 0, Value: foot
// Key: 1, Value: bike
// Key: 2, Value: car
// Key: 3, Value: plane
// 迴圈結束後指標在結尾 (false 位置)
?>

關鍵陷阱與注意事項

1. false 值元素導致迴圈提早結束

current(), next(), prev(), end(), reset() 回傳元素值。若元素值為 false, 0, '', null, [] 等 **falsy 值**,直接用於 `while` 判斷會誤以為結束。


// ❌ 錯誤:元素為 0 或 false 會中斷
while ($val = current($arr)) { next($arr); }

// ✅ 正確:用 key() !== null 判斷指標有效性
reset($arr);
while (key($arr) !== null) {
    $val = current($arr);
    // 處理 $val
    next($arr);
}

// ✅ 更佳:foreach (不影響內部指標,PHP 7+ 複製陣列迭代)
foreach ($arr as $key => $val) { /* ... */ }

2. each() 已棄用 (PHP 7.2+ Deprecated, PHP 8.0+ Removed)

請勿在新代碼使用 `each()`**。改用 `foreach`、`ArrayIterator` 或手動 `key()`/`current()`/`next()` 組合。

3. 參數需為變數引用 (可修改)

所有指標函數參數為傳址呼叫 (內部修改指標位置),必須傳入**變數**,不可直接傳入陣列字面值或函數回傳陣列。


// ❌ 錯誤
current([1,2,3]); // Fatal error: Only variables can be passed by reference

// ✅ 正確
$arr = [1,2,3];
current($arr);

4. 物件迭代

若物件實作 `Traversable` (如 `ArrayIterator`),指標函數也適用。但通常直接 `foreach` 更清晰。

進階實戰場景

場景一:陣列游標實作「上一筆/下一筆」導航

<?php
function getAdjacentItems(array $items, int $currentIndex, int $window = 1): array
{
    // 建立索引陣列 (保證連續數字鍵)
    $indexed = array_values($items);
    $count = count($indexed);
    if ($currentIndex < 0 || $currentIndex >= $count) return [];

    $result = ['current' => $indexed[$currentIndex]];
    
    // 前一筆
    if ($currentIndex - $window >= 0) {
        $result['prev'] = $indexed[$currentIndex - $window];
    }
    // 後一筆
    if ($currentIndex + $window < $count) {
        $result['next'] = $indexed[$currentIndex + $window];
    }
    return $result;
}

// 使用
$articles = [/* ... 文章陣列 ... */];
$currentId = $_GET['id'] ?? 0;
$currentIndex = array_search($currentId, array_column($articles, 'id'));
$nav = getAdjacentItems($articles, $currentIndex);

場景二:手動實作陣列分頁 (不複製大陣列)

<?php
function arrayPage(array &$array, int $page, int $perPage): array
{
    $total = count($array);
    $offset = ($page - 1) * $perPage;
    if ($offset >= $total) return [];

    // 利用指標跳轉 (僅適用數字索引陣列)
    // 實務上 array_slice 較簡潔且不修改原陣列指標
    return array_slice($array, $offset, $perPage, true); // true 保留鍵名
}

場景三:陣列指標與引用陷阱

<?php
$arr = ['a', 'b', 'c'];
$ref = &$arr[1]; // 取得第二個元素的引用

next($arr); // 指標移至 'b'
var_dump(current($arr)); // 'b'

// 修改引用會影響原陣列
$ref = 'B_MODIFIED';
var_dump(current($arr)); // 'B_MODIFIED' (指標所指元素已被修改)
var_dump($arr[1]);       // 'B_MODIFIED'

現代替代方案:ArrayIterator / IteratorAggregate

面向物件、可重用、支援多種迭代模式:

<?php
class ArticleCollection implements IteratorAggregate
{
    private array $articles = [];

    public function add(Article $article): void { $this->articles[] = $article; }

    public function getIterator(): Traversable
    {
        return new ArrayIterator($this->articles);
    }
    
    // 可加入 getPrev(), getNext(), seek() 等自定義方法
}

總結建議

  • **日常迭代**:優先使用 `foreach` (PHP 7+ 複製陣列,不影響內部指標,安全、快速、可讀)。
  • **需手動控制位置**:使用 `reset()`、`end()`、`key()`、`current()`、`next()`/`prev()` 組合,**嚴格用 `key() !== null` 判斷有效性**。
  • **棄用 `each()`**:PHP 8.0+ 已移除。
  • **參數必須是變數**:不可傳字面值陣列。
  • **大型陣列效能**:指標操作避免複製,但 `foreach` PHP 7+ 也極優化。除非極端記憶體敏感,優先考慮可讀性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved