# Strings and Arrays — PHP

Source: https://www.skillbyai.com/en/php/c-arrays

> Work with strings, multibyte text and PHP's ordered-map arrays and their functions.

## The workhorse data types

A PHP **array** is an **ordered map**: keys can be integers or strings, and the same type serves as a list, a dictionary, a stack and a queue. Lists use sequential integer keys (`array_is_list()` checks this). Useful functions: `count`, `in_array` (use the strict third argument), `array_key_exists`, `array_map`, `array_filter` (keeps original keys, so wrap with `array_values` to reindex), `array_reduce`, `array_column`, `array_combine`, `usort` with a comparison closure using the **spaceship operator** `<=>`, `array_slice`, `array_merge` and the spread syntax `[...$a, ...$b]`. Destructuring works with `[$a, $b] = $pair` and `['id' => $id] = $row`. **Strings** are byte strings: functions like `strlen` and `substr` count **bytes**, so for user-visible text in languages such as Hindi use the **`mb_*`** functions (`mb_strlen`, `mb_substr`, `mb_strtoupper`) with UTF-8. PHP 8 added `str_contains`, `str_starts_with` and `str_ends_with`. Use `sprintf` or `number_format` for formatting, and `explode`/`implode` to split and join.

## Arrays and multibyte strings in practice

Group, sort and summarise orders; count characters correctly in Hindi.

```php
<?php
declare(strict_types=1);

$orders = [
    ['id' => 'o-1', 'city' => 'Pune',  'total' => 1200.0],
    ['id' => 'o-2', 'city' => 'Delhi', 'total' => 300.0],
    ['id' => 'o-3', 'city' => 'Pune',  'total' => 800.0],
];

$big = array_values(array_filter($orders, fn (array $o): bool => $o['total'] >= 500));
usort($big, fn (array $a, array $b): int => $b['total'] <=> $a['total']);   // descending

$byCity = [];
foreach ($orders as ['city' => $city, 'total' => $total]) {               // destructuring
    $byCity[$city] = ($byCity[$city] ?? 0) + $total;
}

$ids = array_column($orders, 'id');                // ['o-1', 'o-2', 'o-3']
$hasPune = in_array('Pune', array_column($orders, 'city'), true);

$word = 'नमस्ते';
echo strlen($word), ' bytes, ', mb_strlen($word), ' characters', PHP_EOL;
echo str_contains('order-2026', '2026') ? 'found' : 'missing', PHP_EOL;
```

## array_filter keeps keys

After filtering `[0 => a, 1 => b, 2 => c]` down to `a` and `c`, the keys are `0` and `2`. JSON-encoding that produces an object, not a list. Wrap the result in `array_values()` when you need a list.

**Quiz:** Why use mb_strlen instead of strlen for user-entered text in Hindi?

- [x] strlen counts bytes, while mb_strlen counts characters in multibyte encodings such as UTF-8
- [ ] strlen is deprecated
- [ ] mb_strlen is faster for ASCII
- [ ] strlen only works on numbers

*Answer:* strlen counts bytes, while mb_strlen counts characters in multibyte encodings such as UTF-8. UTF-8 characters can use several bytes, so byte counts differ from character counts.
