Arrays7 min readExamples run on PHP 8.5.10

pos()

Learn how pos(), the alias of current(), reads the element under an array's internal pointer, and how to avoid its false-return ambiguity.

Signature

pos(array|object $array): mixed

Purpose

pos() is an alias of current(). The two names run the same code and behave the same way. Both read the value of the array element that the array's internal pointer currently points to. They do not move the pointer. Movement is the job of next(), prev(), reset() and end().

A fresh array has its pointer at the first element, so pos($array) on a new array returns the first value. Most new code uses current() because the name is clearer. You will still meet pos() in older code, and knowing it is an alias means you only have to learn one behavior.

Signature

This is the PHP 8.4 form. The signature is identical to that of current().

Parameters and defaults

  • $array: the array whose current element you want. It has no default and is required. Pass an array. Objects are accepted by the signature, but their internal property table is an implementation detail you should not rely on.

Return value and failure cases

pos() returns the value stored at the pointer position. The type depends on what is in the array, which is why the declared return type is mixed.

It returns false when:

  • the array is empty, or
  • the pointer has moved past the last element, for example after next() was called on the final element.

It does not throw for an empty array or an exhausted pointer. The only failure is a TypeError if you pass something that is neither an array nor an object, such as a string or null.

Example 1: reading while moving the pointer

The pointer only changes when you move it. Calling pos() repeatedly returns the same value until you call next(), end() or a similar function.

Example
<?php
$fruits = ['apple', 'banana', 'cherry'];

$seen = [];
$seen[] = pos($fruits);
next($fruits);
$seen[] = pos($fruits);
$seen[] = pos($fruits);
end($fruits);
$seen[] = pos($fruits);

echo json_encode($seen, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
["apple","banana","banana","cherry"]

The second and third reads both return banana, because nothing moved the pointer between them.

Example 2: empty arrays and an exhausted pointer

Two different situations produce the same false result: an empty array, and a pointer that has run off the end.

Example
<?php
$empty = [];
$items = ['a'];
next($items);

echo json_encode([pos($empty), pos($items)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
[false,false]

Both calls return false. The $items array is not empty, but its pointer is past the only element.

Example 3: telling a stored false from the end of the array

If an array can contain the value false, the return value alone is ambiguous. Pair pos() with key(). key() returns null when the pointer is beyond the end.

Example
<?php
$flags = [false, true];

$before = [pos($flags), key($flags)];
next($flags);
next($flags);
$after = [pos($flags), key($flags)];

echo json_encode(['before' => $before, 'after' => $after], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
{"before":[false,0],"after":[false,null]}

In before, false is a real element at key 0. In after, false means the pointer is exhausted, and the key is null.

Edge cases

  • Past the end is not a reset. Once the pointer is beyond the last element, pos() keeps returning false until you call reset() or end().
  • Associative arrays. The pointer follows insertion order, not key order. pos() returns the value only, so use key() if you also need the key.
  • Stored false or null. pos() can return a legitimate false or null that was stored in the array. Check key() when that matters.
  • foreach does not use this pointer. Looping with foreach does not move the internal pointer, so the pointer position reflects only calls made through the pointer functions.

Common mistakes

  1. Expecting pos() to advance. It only reads. If you call it in a while loop without calling next(), the loop never ends.
  2. Treating false as "no more elements". An array such as [0, false, 2] contains a real false. Use key() !== null to detect the end.
  3. Assuming pos() is different from current(). It is not. There is no behavioral difference to choose between.
  4. Using it for the last element. pos() returns the last element only if the pointer is already there. Call end() first, or use array_key_last() when you do not want to touch the pointer.
  5. Passing null. A missing array value causes a TypeError, so validate input before calling.
  • current(): the primary name of this function.
  • key(): the key at the pointer, or null past the end.
  • next() and prev(): move the pointer forward or back and return the new value.
  • reset() and end(): move the pointer to the first or last element.
  • array_key_first() and array_key_last(): find boundary keys without using the pointer.

Recap

pos() is exactly current() under another name. It returns the value at the array's internal pointer, or false for an empty array or an exhausted pointer. It never moves the pointer. When false may be a stored value, confirm with key(). In new code, prefer the clearer name current().

Tested examples

Reading while moving the pointer
<?php
$fruits = ['apple', 'banana', 'cherry'];

$seen = [];
$seen[] = pos($fruits);
next($fruits);
$seen[] = pos($fruits);
$seen[] = pos($fruits);
end($fruits);
$seen[] = pos($fruits);

echo json_encode($seen, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
["apple","banana","banana","cherry"]
Empty arrays and an exhausted pointer
<?php
$empty = [];
$items = ['a'];
next($items);

echo json_encode([pos($empty), pos($items)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
[false,false]
Telling a stored false from the end of the array
<?php
$flags = [false, true];

$before = [pos($flags), key($flags)];
next($flags);
next($flags);
$after = [pos($flags), key($flags)];

echo json_encode(['before' => $before, 'after' => $after], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
{"before":[false,0],"after":[false,null]}