Indexed Arrays
What Is an Indexed Array?
In simple terms: An indexed array is a list of values where each value is identified by its position number — 0 for the first item, 1 for the second, and so on. Technically: An indexed array is a PHP array whose keys are sequential integers starting at 0. PHP assigns these keys automatically when values are added without an explicit key. Indexed arrays are used for ordered collections where the position matters more than a name: lists of products, steps, tags, scores, or lines of a file.
$fruits = ['Mango', 'Banana', 'Guava'];
// [0] [1] [2]
Creating Indexed Arrays
Example
<?php
$fruits = ['Mango', 'Banana', 'Guava', 'Papaya'];
$scores = [88, 72, 95];
$empty = [];
print_r($fruits);
echo count($scores) . " scores\n";
echo count($empty) . " items\n";
Output
Array
(
[0] => Mango
[1] => Banana
[2] => Guava
[3] => Papaya
)
3 scores
0 items
PHP numbers the elements automatically, starting at 0. count() returns the number of elements.
Creating Lists With range()
<?php
echo implode(', ', range(1, 5)) . "\n";
echo implode(', ', range(0, 20, 5)) . "\n";
echo implode(', ', range(10, 1, 3)) . "\n";
echo implode(', ', range('a', 'e')) . "\n";
Output
1, 2, 3, 4, 5
0, 5, 10, 15, 20
10, 7, 4, 1
a, b, c, d, e
range($start, $end, $step) generates sequences of numbers or single letters — useful for page numbers, year selectors, or test data.
Accessing Elements by Index
Example
<?php
$fruits = ['Mango', 'Banana', 'Guava', 'Papaya'];
echo $fruits[0] . "\n"; // first
echo $fruits[2] . "\n"; // third
echo $fruits[count($fruits) - 1] . "\n"; // last
echo $fruits[array_key_last($fruits)] . "\n";
Output
Mango
Guava
Papaya
Papaya
Why the Last Index Is count - 1
Indexes start at 0, so an array with 4 elements has indexes 0 to 3. The last index is always one less than the count. array_key_last() (PHP 7.3+) returns the last key directly, which also works when keys have gaps. PHP 8.5 adds array_first() and array_last(), which return the first and last values.
Indexes That Do Not Exist
<?php
$fruits = ['Mango', 'Banana', 'Guava', 'Papaya'];
echo $fruits[10] ?? 'No item at index 10';
echo "\n";
echo $fruits[-1] ?? 'Negative indexes do not count from the end';
echo "\n";
Output
No item at index 10
Negative indexes do not count from the end
- Reading a missing index without
??raisesWarning: Undefined array key 10. - PHP arrays do not support negative indexes from the end.
$fruits[-1]looks for a key literally named-1. (Strings do support negative offsets, but arrays do not.)
Adding and Updating Elements
<?php
$tasks = ['Write lesson', 'Record video'];
$tasks[] = 'Publish'; // append: gets the next index
$tasks[0] = 'Write outline'; // update an existing index
array_unshift($tasks, 'Research'); // add to the beginning
print_r($tasks);
Output
Array
(
[0] => Research
[1] => Write outline
[2] => Record video
[3] => Publish
)
$array[] = $valueappends with the next index (the largest integer key plus one).- Assigning to an existing index replaces that value.
array_unshift()inserts at the beginning and renumbers all indexes. Details are in Add Array Items and Update Array Items.
Removing Elements and Index Gaps
unset() removes an element but does not renumber the remaining ones:
<?php
$queue = ['A', 'B', 'C'];
unset($queue[1]);
$queue[] = 'D';
print_r($queue);
print_r(array_values($queue));
Output
Array
(
[0] => A
[2] => C
[3] => D
)
Array
(
[0] => A
[1] => C
[2] => D
)
Why Gaps Matter
- A
forloop from0tocount() - 1would try to read index1(missing) and miss index3. array_values()returns a new array with the values re-indexed from0.- Functions such as
array_splice(),array_shift(), andarray_pop()remove elements and keep the list properly indexed.
Gaps Change JSON Output
<?php
$list = ['A', 'B', 'C'];
$withGap = [0 => 'A', 2 => 'C'];
echo json_encode($list) . "\n";
echo json_encode($withGap) . "\n";
var_dump(array_is_list($withGap));
echo json_encode(array_values($withGap)) . "\n";
Output
["A","B","C"]
{"0":"A","2":"C"}
bool(false)
["A","C"]
json_encode() produces a JSON array only when the keys are exactly 0, 1, 2, …. With a gap, it produces a JSON object, which can break JavaScript code expecting an array. array_is_list() (PHP 8.1+) checks whether an array is a proper list. Re-index with array_values() before encoding filtered or modified lists.
Looping Over Indexed Arrays
foreach (Recommended)
<?php
$steps = ['Add to cart', 'Enter address', 'Pay'];
foreach ($steps as $index => $step) {
echo ($index + 1) . ". $step\n";
}
Output
1. Add to cart
2. Enter address
3. Pay
for (When You Need Index Arithmetic)
<?php
$steps = ['Add to cart', 'Enter address', 'Pay'];
for ($i = count($steps) - 1; $i >= 0; $i--) {
echo $steps[$i] . "\n";
}
Output
Pay
Enter address
Add to cart
foreach works even when indexes have gaps; for assumes continuous indexes. Use for only when you need the index for calculations such as reverse order or comparing neighbors.
Common List Operations
<?php
$scores = [72, 95, 64, 88, 81];
echo "Highest: " . max($scores) . "\n";
echo "Lowest: " . min($scores) . "\n";
echo "Average: " . array_sum($scores) / count($scores) . "\n";
var_dump(in_array(88, $scores, true));
var_dump(array_search(64, $scores, true));
rsort($scores);
echo "Top 3: " . implode(', ', array_slice($scores, 0, 3)) . "\n";
echo "Reversed: " . implode(', ', array_reverse($scores)) . "\n";
Output
Highest: 95
Lowest: 64
Average: 80
bool(true)
int(2)
Top 3: 95, 88, 81
Reversed: 64, 72, 81, 88, 95
| Function | Purpose |
|---|---|
max(), min(), array_sum() | Calculations |
in_array($value, $list, true) | Does the value exist? |
array_search($value, $list, true) | At which index? (false if not found) |
sort(), rsort() | Sort ascending / descending (re-indexes) |
array_slice($list, $offset, $length) | Extract part of the list |
array_reverse() | Reverse the order |
implode($separator, $list) | Join into a string |
Practical Example: Weekly Temperature Report
<?php
$days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
$temperatures = [31, 33, 30, 35, 34, 32, 29];
$hottestIndex = array_search(max($temperatures), $temperatures, true);
$coldestIndex = array_search(min($temperatures), $temperatures, true);
$average = array_sum($temperatures) / count($temperatures);
$aboveAverage = [];
for ($i = 0, $n = count($temperatures); $i < $n; $i++) {
if ($temperatures[$i] > $average) {
$aboveAverage[] = $days[$i];
}
}
echo "Hottest: {$days[$hottestIndex]} ({$temperatures[$hottestIndex]}°C)\n";
echo "Coldest: {$days[$coldestIndex]} ({$temperatures[$coldestIndex]}°C)\n";
echo "Average: {$average}°C\n";
echo "Above average: " . implode(', ', $aboveAverage) . "\n";
Output
Hottest: Thu (35°C)
Coldest: Sun (29°C)
Average: 32°C
Above average: Tue, Thu, Fri
Step-by-Step Explanation
- Two parallel indexed arrays hold the days and the temperatures; the same index connects a day to its temperature.
array_search(max(...))finds the index of the highest temperature, which is then used to look up the day name.- The average is
224 / 7 = 32. Because the division is exact, the result is an integer. - The
forloop uses the index to read from both arrays at once — a case where index arithmetic is genuinely useful. Parallel arrays work, but they are fragile: if one array is sorted or modified, the pairs no longer line up. Combining them into an associative array witharray_combine($days, $temperatures)keeps each day and temperature together (see Associative Arrays).
Common Mistakes
Off-by-One Errors
Effect: $list[count($list)] reads past the end; <= in a for loop runs one iteration too many. Fix: The last index is count($list) - 1; use < in loops, or foreach.
Expecting Negative Indexes to Work
Effect: $list[-1] is an undefined key. Fix: Use $list[array_key_last($list)], end($list), or array_last($list) (PHP 8.5+).
Forgetting That unset() Leaves Gaps
Effect: Missing indexes in for loops and JSON objects instead of arrays. Fix: Re-index with array_values(), or use array_splice().
Loose in_array() and array_search()
Effect: Unexpected matches between strings and numbers. Fix: Pass true for strict comparison.
Checking array_search() Results Loosely
Effect: A match at index 0 is treated as "not found". Fix: Compare with !== false.
Best Practices
- Use indexed arrays for ordered lists where position matters.
- Loop with
foreachunless you need index calculations. - Re-index with
array_values()after removing elements, especially before JSON encoding. - Use
array_key_last()orarray_last()instead of manualcount() - 1when keys may have gaps. - Prefer associative arrays (or arrays of records) over parallel arrays. Official reference: https://www.php.net/manual/en/language.types.array.php