skip to content

Array Operations

PHP's one array type is an ordered hash map, both list and dictionary, worked through array_* helpers, sort functions and destructuring. Nearly all PHP data flows through it, so interviewers probe it.

part ofPHPoverview, primer and where to startread it →
on this pageshow

explore

questions

21

In PHP, how do you destructure an array into separate variables with [] or list(), both by position and by key?

level: juniorimportance: must knowfreq 55%

answer

  1. an array pattern on the left of =
  2. positional reads keys 0, 1, 2
  3. 'lat' => $lat picks by key
  4. empty slot skips an element
  5. [$a, $b] = [$b, $a] swaps

basics

~20 s

Put an array pattern on the left of =: [$lat, $lng] = $point copies the elements at keys 0 and 1, and ['lat' => $lat] = $point copies by key. list() is the older spelling of the same construct.

solid answer

~40 s

Destructuring assigns several variables from one array in a single statement. The short form `[$lat, $lng] = $point;` and the older `list($lat, $lng) = $point;` are the same construct. A **positional** pattern reads keys `0`, `1`, `2`, … in that order, not "the first and second elements". A **keyed** pattern names the keys: `['lat' => $lat, 'lng' => $lng] = $point;`, and the keys can be any expression. Leave a slot empty to skip an element (`[, $lng] = $point`), nest patterns for nested arrays, and swap two variables with `[$a, $b] = [$b, $a];`. One pattern cannot mix keyed and unkeyed entries, and a missing key yields `null` plus an `E_WARNING` in PHP 8.

code

php · 14 lines
php
<?php
declare(strict_types=1);

// One track point from a hiking-route API: [lat, lng, elevation]
$trackPoint = [46.5580, 7.9812, 2061];

[$lat, $lng] = $trackPoint;          // positional: keys 0 and 1
[, , $elevation] = $trackPoint;      // skip two slots

$start = ['lat' => 46.5580, 'lng' => 7.9812];
['lng' => $lng2, 'lat' => $lat2] = $start;   // keyed, any order

[$lat, $lng] = [$lng, $lat];         // swap
echo "$lat $lng $elevation $lat2", PHP_EOL; // 7.9812 46.558 2061 46.558

go deeper

for a junior

Recall both spellings, [] and list(), the keyed form with =>, skipping with an empty slot and the one-line swap.

for a middle

Explain that positional patterns read keys 0, 1, 2 rather than the first elements, why keyed and unkeyed entries cannot mix, and what a missing key does.

for a senior

Use keyed patterns for external payloads so a shape change fails visibly, and review positional unpacking of associative data as a latent null bug.

for a principal

Decide where arrays stop and typed objects begin: destructuring is fine at the edge, but a shape used across many functions deserves a named class the tooling can check.

## What destructuring is **Destructuring** (also called unpacking) assigns several variables from one array in one statement. You write an array-shaped **pattern** on the left of `=` and an array on the right; each variable in the pattern receives the element at the matching key. PHP has two spellings for the pattern: - `[$lat, $lng] = $point;` — the short square-bracket form, the usual choice in modern code. - `list($lat, $lng) = $point;` — the older `list()` construct. It is not a function, and it behaves exactly the same. The whole assignment expression evaluates to the right-hand array, which is why the old idiom `while ([$a, $b] = nextRow())` works: when the call returns `null`, the loop condition is falsy. ## Positional patterns read keys 0, 1, 2 A pattern without keys is positional, and it is easy to misread. It does **not** take "the first two elements"; it takes the elements whose keys are `0` and `1`: | Right-hand side | `[$lat, $lng] = …` gives | |---|---| | `[46.55, 7.98]` | `$lat = 46.55`, `$lng = 7.98` | | `[1 => 7.98, 0 => 46.55]` | `$lat = 46.55`, `$lng = 7.98` (keys win over order) | | `['lat' => 46.55, 'lng' => 7.98]` | both `null`, plus two `Undefined array key` warnings | So a positional pattern suits **lists**, such as the `[lat, lng]` pairs a hiking-route API returns for each track point, or the result of `explode()`. ## Keyed patterns For associative arrays, name the keys: ```php ['lat' => $lat, 'lng' => $lng] = $point; ``` - Keys can be strings, integers or any expression, such as a constant or a variable. - Order does not matter, and you can pick only the keys you need. - Integer keys let you pick from a list by position: `[2 => $elevation] = $trackPoint;`. Keyed patterns are the self-documenting choice for API payloads: the code says which field goes into which variable. ## Skipping, nesting and swapping 1. **Skip** an element by leaving its slot empty: `[, $lng] = $point;` or `[$lat, , $elevation] = $trackPoint;`. 2. **Nest** patterns to reach into nested arrays: `['start' => [$lat, $lng]] = $route;`. 3. **Swap** two variables without a temporary: `[$a, $b] = [$b, $a];`. The right-hand array is built from the old values first, then unpacked. 4. **Bind by reference** with `&`: after `[$lat, &$lng] = $point;`, writing to `$lng` changes `$point[1]`. ## Rules the compiler enforces Some patterns are rejected before the script runs: - **Mixing keyed and unkeyed entries** in one pattern, as in `[$id, 'name' => $name] = $row;`, is a fatal compile error: "Cannot mix keyed and unkeyed array entries in assignments". Nested patterns may each choose their own style. - **A pattern with no variables at all**, only empty slots such as `list(, ,) = $point;`, fails with "Cannot use empty list". - **A rest element** such as `[$head, ...$tail] = $items;` fails with "Spread operator is not supported in assignments"; the spread operator only works when *building* arrays. ## What happens when the data does not fit In PHP 8 a key missing from the right-hand array raises an `E_WARNING` ("Undefined array key") and assigns `null`; before PHP 8.0 it was an `E_NOTICE`. The code keeps running with `null` in the variable, so a pattern that does not match the data's shape is a quiet bug rather than a crash. Checking the shape at the boundary, or using keyed patterns against a documented payload, keeps that from spreading. ## Why interviewers ask about it Destructuring shows up in everyday modern PHP: splitting `explode()` results, unpacking pairs returned from a helper, iterating over rows. The screening version checks that a candidate knows the syntax; the follow-ups check that they know positional patterns read keys `0`, `1`, `2`, and that a mismatch yields `null` rather than an exception. ## Choosing a style - Positional `[$a, $b]` for true lists whose order is the contract: coordinate pairs, `explode()` results, rows fetched as numeric arrays. - Keyed `['lat' => $lat]` for associative data: decoded JSON objects, configuration arrays, database rows fetched by column name. - A small typed object instead, when the same shape travels through many functions and deserves a name.

  • Why does [$lat, $lng] = ['lat' => 46.55, 'lng' => 7.98] leave both variables null?
    A positional pattern reads the keys `0` and `1`, and this array has only the string keys `lat` and `lng`. Each lookup misses, PHP 8 raises an `Undefined array key` warning and assigns `null`. Use a keyed pattern, `['lat' => $lat, 'lng' => $lng] = $point;`, for associative data.
  • Can you destructure an object into variables?
    Only if it implements `ArrayAccess`; the pattern then calls `offsetGet()` for each key. A plain object such as `stdClass` throws an `Error` ("Cannot use object of type stdClass as array"). For ordinary objects, read the properties directly or convert the data to an array first.

saying these in an interview costs you the question

  • A positional pattern takes the first elements whatever their keys
  • list() is a function that returns the unpacked values
  • One pattern can mix keyed and positional entries
  • Swapping two variables with destructuring needs a temporary variable
  • [$head, ...$tail] = $items collects the remaining elements
open as a page

In PHP, what is the difference between array_merge() and the + union operator when both arrays share keys?

level: juniorimportance: must knowfreq 68%

basics

~10 s

array_merge() lets later arrays overwrite earlier ones for string keys but appends and renumbers integer keys; $a + $b keeps every key of $a, adds only keys missing from $a, and never renumbers.

open as a page

In PHP, if you assign an array to another variable or pass it to a function and modify that copy, what happens to the original?

level: juniorimportance: must knowfreq 58%

basics

~20 s

Nothing: PHP arrays are values, so assignment and by-value parameters give an independent copy, and changing it leaves the original intact. Objects stored inside are handles, so both copies still point to the same objects.

open as a page

In PHP, what does it mean that an array is an ordered map, and how do indexed and associative arrays differ?

level: juniorimportance: must knowfreq 72%

basics

~20 s

A PHP array is one ordered map from int or string keys to values of any type. Indexed and associative arrays are the same type: an indexed array just has keys 0, 1, 2, and every array keeps insertion order.

open as a page

In PHP, what is the difference between sort(), asort() and ksort(), and which of them keep an array's keys?

level: juniorimportance: must knowfreq 70%

basics

~10 s

sort() orders the values and renumbers the keys 0, 1, 2; asort() orders the values but keeps each key with its value; ksort() orders by key. All three sort in place and return true.

open as a page

In PHP, how does the ... spread operator work inside an array literal, and what changed for string keys in PHP 8.1?

level: middleimportance: must knowfreq 48%

basics

~10 s

[...$a, ...$b] copies the elements of arrays or Traversables into a new array: integer keys are renumbered, and since PHP 8.1 string keys are kept with later values overwriting earlier ones, like array_merge().

open as a page

In PHP, which keys survive array_map() and array_filter(), and how do you filter by key with ARRAY_FILTER_USE_KEY?

level: middleimportance: must knowfreq 55%

basics

~10 s

array_filter() keeps the original keys, so a filtered list has gaps until array_values(); array_map() keeps keys only when given exactly one array. ARRAY_FILTER_USE_KEY passes each key to the callback, ARRAY_FILTER_USE_BOTH passes value then key.

open as a page

In PHP, how are array keys like "8", "08", true, 8.7 and null converted, and why do ZIP-code keys end up with mixed types?

level: middleimportance: must knowfreq 55%

basics

~20 s

A string key that is a canonical decimal integer, like "8" or "-8", is stored as int; "08" stays a string. true becomes 1, 8.7 becomes 8 and null becomes "", so ZIP code "90210" returns as int while "02134" stays string.

open as a page

In PHP, how do you write a usort() comparator with the <=> operator, and when do you switch to uasort() or uksort()?

level: middleimportance: must knowfreq 58%

basics

~20 s

A usort() comparator takes two elements and returns an int below, at or above zero; $a <=> $b does that in one expression. usort() renumbers keys, uasort() keeps them, and uksort() compares the keys instead.

open as a page

In PHP 8.5, what does a destructuring assignment like [$lat, $lng] = $point do when $point lacks those keys or is not an array?

level: middleimportance: should knowfreq 30%

basics

~20 s

Missing keys raise an E_WARNING and assign null. A null right-hand side assigns null silently; since PHP 8.5 an int, float, string or bool does the same but warns. A plain object throws an Error unless it implements ArrayAccess.

open as a page

In PHP, how do you destructure nested arrays directly in a foreach loop, such as a route's list of latitude and longitude pairs?

level: middleimportance: should knowfreq 35%

basics

~10 s

Write a pattern where the value variable goes: foreach ($track as [$lat, $lng]) unpacks each pair. Keys still work ($i => [$lat, $lng]), keyed patterns pick fields, and patterns nest to reach inner arrays.

open as a page

In PHP, how would you summarise a bakery app's orders by customer using array_column(), array_combine() and array_reduce(), and where does each fall short?

level: middleimportance: should knowfreq 40%

basics

~20 s

array_column() extracts one field, optionally keyed by another, but duplicate index values overwrite, so it cannot group. array_reduce() with an [] initial value builds per-customer totals; array_combine() pairs two lists and throws ValueError on a length mismatch.

open as a page

In PHP 8, why should in_array() and array_search() usually be called with the strict flag, and how do you test array_search()'s result?

level: middleimportance: should knowfreq 48%

basics

~20 s

Without strict true, in_array() and array_search() compare with ==, so null matches 0 and '', and '1e1' matches '10'. array_search() returns the key or false, and key 0 is falsy, so test its result with === false.

open as a page

In PHP, which key does $arr[] = $value assign, and why does it skip numbers after elements are unset?

level: middleimportance: should knowfreq 38%

basics

~20 s

$arr[] = $value uses one more than the largest integer key the array has held since it was last re-indexed, or 0 if it never had one. unset() does not lower that counter, so appended keys can skip numbers until array_values() re-indexes.

open as a page

In PHP, how do the SORT_STRING, SORT_NATURAL and SORT_FLAG_CASE flags change the order that sort() produces for strings?

level: middleimportance: should knowfreq 35%

basics

~10 s

SORT_STRING compares values as strings byte by byte, so '10' sorts before '2'; SORT_NATURAL orders digit runs by number, so 'img2' precedes 'img10'; SORT_FLAG_CASE, OR-ed with either, ignores ASCII letter case.

open as a page

In PHP, what do compact() and extract() do, and why do most code reviews reject extract() in application code?

level: seniorimportance: should knowfreq 30%

basics

~20 s

compact('lat', 'lng') builds ['lat' => $lat, 'lng' => $lng] from variable names; extract($array) does the reverse, creating a variable per key and by default overwriting existing ones. Reviews reject extract() because data decides which variables exist.

open as a page

In PHP, when would you use array_walk() or a foreach instead of chained array_map() and array_filter() calls on a large order export?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Each array_map() or array_filter() call builds a complete new array, so a chain over a large export holds several full-size arrays in memory. A single foreach, or array_walk() when values are changed in place, does the work in one pass without intermediates.

open as a page

In PHP 8.1 and later, what does array_is_list() check, and how does that relate to the engine's packed array layout?

level: seniorimportance: should knowfreq 25%

basics

~20 s

array_is_list(), added in PHP 8.1, returns true when the keys are exactly 0, 1, 2 and so on in iteration order, with no gaps or string keys. Packed layout is an internal memory optimisation; array_is_list() tests the keys, not the layout.

open as a page

Since PHP 8.0 every PHP sort function is stable; what does that guarantee, and how would you rely on it to break leaderboard ties?

level: seniorimportance: should knowfreq 28%

basics

~20 s

A stable sort keeps elements that compare equal in the order they had before the sort. PHP guarantees this for every sort function since 8.0, so sorting by a secondary key first and the primary key second yields a tie-broken order.

open as a page

In PHP 8.4 and 8.5, what do array_find(), array_any(), array_all(), array_first() and array_last() return, and what did they replace?

level: middleimportance: nice to knowfreq 22%

basics

~20 s

PHP 8.4 added array_find() (first matching value or null), array_find_key(), array_any() and array_all(), which stop at the deciding element. PHP 8.5 added array_first() and array_last(), returning the first or last value or null for an empty array.

open as a page

In PHP, how does array_multisort() sort a rowset by several columns, and what happens to the keys of the arrays it reorders?

level: middleimportance: nice to knowfreq 20%

basics

~20 s

array_multisort() takes several equal-length arrays, each optionally followed by SORT_ASC/SORT_DESC and a flag, sorts by the first and breaks ties with the next, and reorders all of them together. String keys survive; integer keys are renumbered.

open as a page