data types and standard library

Arrays

PHP arrays are used for lists, maps, and lightweight records, so the first skill is recognising the shape of the data before choosing a function.

You already met basic arrays in the PHP language track. This lesson focuses on the standard-library functions you will use when data has already arrived from a request, database query, API response, CSV file, or configuration file.

Start with the array shape

A list uses numeric positions:

PHP example
<?php

declare(strict_types=1);

$productNames = ['keyboard', 'mouse', 'monitor'];

echo $productNames[0] . PHP_EOL;

// Prints:
// keyboard

A map uses meaningful keys:

PHP example
<?php

declare(strict_types=1);

$stockBySku = [
    'KB-101' => 12,
    'MS-202' => 0,
];

echo $stockBySku['KB-101'] . PHP_EOL;

// Prints:
// 12

A list of records is usually an array of associative arrays:

PHP example
<?php

declare(strict_types=1);

$orders = [
    ['id' => 1, 'status' => 'paid', 'total' => 1250],
    ['id' => 2, 'status' => 'draft', 'total' => 800],
];

echo $orders[0]['status'] . PHP_EOL;

// Prints:
// paid

Many array bugs come from treating one shape as another. Before you reach for array_map() or array_column(), ask: is this a plain list, a keyed map, or a list of records?

Pulling a column from records

array_column() is useful when you have a list of records and need one field from each record.

PHP example
<?php

declare(strict_types=1);

$orders = [
    ['id' => 1, 'status' => 'paid', 'total' => 1250],
    ['id' => 2, 'status' => 'paid', 'total' => 800],
];

$totals = array_column($orders, 'total');
$grandTotal = array_sum($totals);

echo 'Grand total: ' . $grandTotal . ' pennies' . PHP_EOL;

// Prints:
// Grand total: 2050 pennies

This is common after fetching rows from a database or decoding JSON. The code is short, but it only makes sense if every record is expected to contain a total key.

Filtering rows

array_filter() keeps values that pass a test. When filtering a list, call array_values() afterwards if you need a clean zero-based list.

PHP example
<?php

declare(strict_types=1);

$orders = [
    ['id' => 1, 'status' => 'paid', 'total' => 1250],
    ['id' => 2, 'status' => 'draft', 'total' => 800],
    ['id' => 3, 'status' => 'paid', 'total' => 2199],
];

$paidOrders = array_values(array_filter($orders, function (array $order): bool {
    return $order['status'] === 'paid';
}));

echo count($paidOrders) . ' paid orders' . PHP_EOL;

// Prints:
// 2 paid orders

array_filter() preserves the original keys. That is useful for maps, but it can surprise you with lists because the first remaining item may no longer be at index 0.

Mapping values

array_map() transforms each value and returns a new array. Use it when you want the same operation applied to each item.

PHP example
<?php

declare(strict_types=1);

$names = ['keyboard', 'mouse', 'monitor'];

$labels = array_map(function (string $name): string {
    return ucfirst($name);
}, $names);

echo implode(', ', $labels) . PHP_EOL;

// Prints:
// Keyboard, Mouse, Monitor

Mapping should not normally change external state. If the callback is sending emails, writing files, or updating a database, a foreach loop is usually clearer.

Reducing values

array_reduce() turns an array into one final value.

PHP example
<?php

declare(strict_types=1);

$lines = [
    ['quantity' => 2, 'unitPrice' => 500],
    ['quantity' => 1, 'unitPrice' => 1299],
];

$total = array_reduce(
    $lines,
    function (int $carry, array $line): int {
        return $carry + ($line['quantity'] * $line['unitPrice']);
    },
    0
);

echo 'Basket total: ' . $total . ' pennies' . PHP_EOL;

// Prints:
// Basket total: 2299 pennies

array_reduce() is useful for totals, summaries, and grouped values. If the callback becomes hard to read, write a small named function or use a foreach loop instead.

Sorting arrays

Different sort functions preserve different things. sort() reindexes values, while asort() preserves keys.

PHP example
<?php

declare(strict_types=1);

$stockBySku = [
    'KB-101' => 12,
    'MS-202' => 3,
    'MN-303' => 8,
];

asort($stockBySku);

foreach ($stockBySku as $sku => $stock) {
    echo $sku . ': ' . $stock . PHP_EOL;
}

// Prints:
// MS-202: 3
// MN-303: 8
// KB-101: 12

Choose the sorting function based on whether the keys matter. Product IDs, slugs, and database IDs usually matter.

Merging arrays

array_merge() appends numeric-keyed values and lets later string-keyed values replace earlier ones.

PHP example
<?php

declare(strict_types=1);

$defaults = [
    'currency' => 'GBP',
    'perPage' => 20,
];

$requestOptions = [
    'perPage' => 50,
];

$options = array_merge($defaults, $requestOptions);

echo $options['currency'] . ' ' . $options['perPage'] . PHP_EOL;

// Prints:
// GBP 50

This is useful for options and configuration. Be careful when the arrays contain numeric keys, because merging a list is different from replacing named options.

Handling missing keys

Do not assume a key exists when data comes from outside your code. Check it at the boundary and fail with a useful message.

PHP example
<?php

declare(strict_types=1);

function requireOrderTotal(array $order): int
{
    if (!array_key_exists('total', $order)) {
        throw new InvalidArgumentException('Order total is required.');
    }

    if (!is_int($order['total'])) {
        throw new InvalidArgumentException('Order total must be an integer.');
    }

    return $order['total'];
}

echo requireOrderTotal(['id' => 1, 'total' => 1250]) . PHP_EOL;

// Prints:
// 1250

Use array_key_exists() when null is a possible value and you need to know whether the key exists. Use isset() when null should behave like a missing value.

What to remember

Arrays are flexible, but that flexibility is also the risk. Name variables after the shape they contain, such as $paidOrders, $stockBySku, or $totals. Validate records from external sources before transforming them. Prefer readable loops when nested array functions become difficult to explain in a code review.

Practice

Task: Build an order summary

Build a small order summary from an array of order records.

Requirements

  • Use declare(strict_types=1);.
  • Start with an array containing at least three orders.
  • Each order should contain id, status, and total.
  • Keep only orders with the status paid.
  • Reindex the filtered list.
  • Pull the paid order IDs into their own array.
  • Pull the paid totals into their own array and sum them.
  • Print the paid order IDs and the grand total.
  • Include the expected output as comments in the same PHP code block.

The finished example should make it clear when you are filtering records, when you are extracting columns, and when you are calculating the final total.

Show solution
PHP example
<?php

declare(strict_types=1);

$orders = [
    ['id' => 1, 'status' => 'paid', 'total' => 1250],
    ['id' => 2, 'status' => 'draft', 'total' => 800],
    ['id' => 3, 'status' => 'paid', 'total' => 2199],
];

$paidOrders = array_values(array_filter($orders, function (array $order): bool {
    return $order['status'] === 'paid';
}));

$paidOrderIds = array_column($paidOrders, 'id');
$paidTotals = array_column($paidOrders, 'total');
$grandTotal = array_sum($paidTotals);

echo 'Paid orders: ' . implode(', ', $paidOrderIds) . PHP_EOL;
echo 'Grand total: ' . $grandTotal . ' pennies' . PHP_EOL;

// Prints:
// Paid orders: 1, 3
// Grand total: 3449 pennies

This solution separates the work into clear stages. array_filter() chooses the records, array_values() turns the result back into a normal list, array_column() extracts the fields needed for output and calculation, and array_sum() produces the final total.