Lesson 9 of 12

PHP Arrays

An array holds many values under one variable name. A shopping cart, a list of cities, the fields of a submitted form and the rows returned from a database are all arrays in PHP. Arrays are probably the data structure you will use most, so this lesson is a little longer. It builds on PHP Loops and PHP Functions.

Indexed and associative arrays

You create an array with square brackets. PHP arrays come in two flavours, although technically they are the same type:

  • Indexed arrays use automatic number keys starting at 0: ["Tea", "Coffee"]. Item 0 is “Tea”.
  • Associative arrays use keys you choose, usually strings: ["name" => "Anu", "city" => "Vellore"]. They work like a small record or a dictionary.

Read an item with its key in square brackets. Add an item to the end of an indexed array with empty brackets, $list[] = "Juice";, and remove one with unset(). For debugging, print_r() prints an array in a readable form.

<?php
$drinks = ["Tea", "Coffee", "Buttermilk"];
echo $drinks[0], "\n";          // first item
echo count($drinks), " drinks\n";

$drinks[] = "Badam milk";       // add to the end
unset($drinks[1]);              // remove "Coffee"

$student = [
    "name"  => "Anu",
    "city"  => "Vellore",
    "marks" => 88,
];
$student["course"] = "BCA";     // add a new key

echo "{$student['name']} from {$student['city']} studies {$student['course']}\n";
print_r($drinks);
Output
Tea
3 drinks
Anu from Vellore studies BCA
Array
(
    [0] => Tea
    [2] => Buttermilk
    [3] => Badam milk
)

Look at the keys in the print_r() output: after unset(), the key 1 is simply missing. PHP does not renumber indexed arrays. If you need clean keys again, pass the array through array_values().

Watch out: Reading a key that does not exist, such as $student["phone"], triggers an “Undefined array key” warning. Check with isset() or array_key_exists() first, or use the null coalescing operator: $student["phone"] ?? "not given".

Multidimensional arrays

An array can contain other arrays. The most common shape is a list of records: an indexed array where each item is an associative array. This is exactly the shape you get when you fetch rows from a database with PDO, so it is worth getting comfortable with now.

<?php
$products = [
    ["name" => "Cotton kurta",   "price" => 799,  "stock" => 12],
    ["name" => "Silk dupatta",   "price" => 1250, "stock" => 0],
    ["name" => "Handloom towel", "price" => 249,  "stock" => 40],
];

foreach ($products as $product) {
    $status = $product["stock"] > 0 ? "in stock" : "sold out";
    echo "{$product['name']}: Rs. {$product['price']} ({$status})\n";
}

$prices = array_column($products, "price");
echo "Prices: ", implode(", ", $prices), "\n";
echo "Total of all prices: ", array_sum($prices), "\n";
echo "Second product: ", $products[1]["name"];
Output
Cotton kurta: Rs. 799 (in stock)
Silk dupatta: Rs. 1250 (sold out)
Handloom towel: Rs. 249 (in stock)
Prices: 799, 1250, 249
Total of all prices: 2298
Second product: Silk dupatta

array_column() pulls one field out of every record, and array_sum() adds the numbers together. To reach a value deep inside, chain the keys: $products[1]["name"] means “the name of the second product”.

Arrays are copied, not shared

When you assign an array to another variable, or pass it to a function, PHP gives the receiver its own copy. Changing $copy = $products; $copy[0]["price"] = 0; leaves $products untouched. This is different from JavaScript, where arrays are shared by reference. It makes PHP code safer to reason about: a function that receives an array cannot quietly change your original. If a function should change an array, have it return the new version and assign the result.

Searching PHP arrays

FunctionReturns
in_array($value, $array, true)true if the value exists. Always pass true as the third argument for strict comparison.
array_search($value, $array, true)The key of the first match, or false.
array_key_exists($key, $array)true if the key exists, even when its value is null.
isset($array[$key])true if the key exists and the value is not null.

Tip: Without the third argument, in_array() uses loose comparison, so in_array("1e1", ["10"]) is true. Strict mode avoids this, in the same spirit as === from PHP Operators.

Sorting arrays

PHP sorts arrays in place: the functions change the original array and return true. Pick the function by what you want to keep:

  • sort() / rsort(): sort values ascending / descending and renumber the keys.
  • asort() / arsort(): sort by value but keep each key with its value.
  • ksort() / krsort(): sort by key.
  • usort(): sort with your own comparison function, ideal for lists of records.
<?php
$scores = ["Ravi" => 72, "Asha" => 91, "John" => 85];
arsort($scores);                       // highest first, keep names
foreach ($scores as $name => $score) {
    echo "$name: $score\n";
}

$hotels = [
    ["name" => "Lake View",  "rating" => 4.2],
    ["name" => "Hill Top",   "rating" => 4.7],
    ["name" => "Town Lodge", "rating" => 3.9],
];
usort($hotels, fn(array $a, array $b): int => $b["rating"] <=> $a["rating"]);
echo "Top rated: ", $hotels[0]["name"], "\n";

[$first, $second] = ["Ooty", "Kodaikanal"];   // destructuring
echo "$first and $second";
Output
Asha: 91
John: 85
Ravi: 72
Top rated: Hill Top
Ooty and Kodaikanal

The comparison function passed to usort() must return a negative number, zero or a positive number. The spaceship operator <=> produces exactly that, and swapping $a and $b reverses the order. The last two lines show destructuring: unpacking array items straight into variables.

Other functions worth knowing

array_map() transforms every item, array_filter() keeps only the items that pass a test, array_merge() joins arrays, array_keys() and array_values() return the keys or values, and array_slice() takes a portion. You saw array_map() and array_filter() with arrow functions in the previous lesson. Browse the php.net array function list once; knowing what exists saves you from writing loops PHP already provides.

Next, PHP Forms shows that submitted form data arrives as associative arrays called $_GET and $_POST.

Further reading

Key takeaways

  • Indexed arrays have number keys from 0; associative arrays use your own keys with =>.
  • Add with $arr[] = value, remove with unset(), count with count().
  • A list of associative arrays is the standard shape for records, such as database rows.
  • Use in_array(..., true) for strict searching and ?? or isset() for possibly missing keys.
  • Sort with sort, asort, ksort or usort plus <=> for records.

Quick quiz

Check what you learned – pick an answer.

1. Given $colours = ["red", "green", "blue"];, what is $colours[1]?

2. Which function sorts an associative array by value while keeping the keys?

3. What is the safest way to read $user["phone"] when the key might not exist?

Practice exercise

Create an array of three books, each with title, author and price. Sort the books by price from lowest to highest with usort(), then print each one as "Title by Author – Rs. Price", followed by the average price rounded to 2 decimals.

Show a hint

Use array_column() and array_sum() for the average, and count() for the number of books.

Show the solution
<?php
$books = [
    ["title" => "Ponniyin Selvan", "author" => "Kalki", "price" => 650],
    ["title" => "Wings of Fire", "author" => "A. P. J. Abdul Kalam", "price" => 299],
    ["title" => "Malgudi Days", "author" => "R. K. Narayan", "price" => 350],
];

usort($books, fn(array $a, array $b): int => $a["price"] <=> $b["price"]);

foreach ($books as $book) {
    echo "{$book['title']} by {$book['author']} – Rs. {$book['price']}n";
}

$average = array_sum(array_column($books, "price")) / count($books);
echo "Average price: Rs. " . round($average, 2); // 433

Progress is saved in this browser only.