1.5Arrays & strings
The essentials in 30 seconds
- Indexed = list, associative = named data: $tab[0] by position, $tab['nom'] by key — choose according to nature.
- Multidimensional = the shape of the web: list of associative rows — exactly a query result, iterated with foreach.
- Do not reinvent: count, in_array, array_map/filter, implode/explode, str_replace, trim… — and mb_* for Unicode.
Running mini-case — Riad structures his data in Constantine
Riad receives the list of services with their rates: he first stores them in separate variables $p1, $p2, $p3 — and gets tangled from the fourth one on. He restructures into an associative array per service, then into a multidimensional list ready for foreach display. He replaces his home-made search loop with in_array, his manual counting with count, and fixes a strlen cutting an accented title by switching to mb_strlen. His data finally has a shape that grows without breaking.
Last episode of cases 1.1-1.4 — Riad structures his data after variables, decisions, loops and functions.
1. Arrays, the central structure
Arrays are THE data structure of PHP. The indexed array: access by numeric index (from 0) — $fruits = ['apple', 'banana']; $fruits[0]. The associative array: access by a text key — $personne = ['nom' => 'Alice']; $personne['nom'] (everywhere: structured data). Arrays can be multidimensional (arrays inside arrays — e.g. a list of users). Iterate them with foreach, count with count(), append with $tab[] = value;.
Riad stores his services as a list of associatives (name + rate each): adding a service means adding a row — never a $p4 variable again.
2. Native functions & Unicode
PHP has hundreds of native functions. Arrays: count, in_array, array_map (transform), array_filter (filter), array_reduce (aggregate), implode / explode. Strings: strlen, str_replace, substr, trim, str_contains (PHP 8). Reflex: do not reinvent what exists (the official docs are excellent). Unicode caution: classic functions work on BYTES (a problem with accents in UTF-8) — use multi-byte functions (mb_strlen, mb_substr).
Riad counts with count, searches with in_array, and measures his accented titles with mb_strlen: three home-made loops removed, one display fixed.
🔎 Concrete example — 🔎 Concrete example — Indexed, associative, multidimensional
The shape of web data, like Riad for his services.
$utilisateurs = [
['nom' => 'Alice', 'age' => 30],
['nom' => 'Bob', 'age' => 25],
];
foreach ($utilisateurs as $u) {
echo htmlspecialchars($u['nom']) . ' ';
}
echo count($utilisateurs); // 2
Reading: exactly the shape of a query result (list of rows), iterated with foreach.
Lesson: safe key access with ?? ($tab['cle'] ?? default) — never a surprise missing key.
Section vocabulary
- Indexed array
- Collection whose elements are reachable by a NUMERIC index (from 0): $fruits = ['apple', 'banana']; $fruits[0].
Simple example: Riad's list of service names.
What it is not: an associative for a simple ordered list.
Reflex: homogeneous list, order that matters = indexed.
- Associative array
- Collection whose elements are reachable by a TEXT key: $personne = ['nom' => 'Alice']; $personne['nom']. Everywhere (structured data).
Simple example: Each of Riad's services (named name + rate).
What it is not: $prestation[1] instead of $prestation['tarif'].
Reflex: named data = explicit keys.
- Multidimensional array
- Arrays INSIDE arrays (e.g. a list of users, each an associative array); represents complex data.
Simple example: Riad's full catalogue, listed then displayed.
What it is not: separate $p1, $p2, $p3 variables.
Reflex: list of entities = indexed of associatives.
- Array/string functions
- Hundreds of native functions: arrays (count, in_array, array_map/filter/reduce, sort, implode/explode…), strings (strlen, str_replace, substr, trim, str_contains…).
Simple example: The count and in_array replacing Riad's home-made loops.
What it is not: a manual loop to find a value.
Reflex: before a loop: does the native exist?
- Multi-byte (mb_) functions
- To correctly handle Unicode (accented/non-Latin characters): mb_strlen, mb_substr…; classic functions work on bytes (a problem in UTF-8).
Simple example: Riad's accented title measured with mb_strlen.
What it is not: truncating "search engine optimisation" with substr and cutting a character.
Reflex: accented text = systematic mb_*.
In practice — In practice — Handling arrays and strings
- Create an indexed array and an associative array; access their elements (by index / by key) and append an element (`$tab[] = ...`).
- Create a multidimensional array (e.g. a list of users, each an associative array) and iterate it with foreach.
- Use array functions: count, in_array, array_map (transform), array_filter (filter), implode/explode.
- Handle strings: strlen, str_replace, substr, trim, strtolower; and spot the multi-byte functions (mb_strlen) for Unicode.
Ready-to-say script — defending the native function (30 s)
"Before writing this loop, let's check whether a native exists: in_array searches, array_filter filters, implode joins — proven, fast, readable. Let's reserve our code for business logic, not rewriting what PHP already does."
Say in code review; open php.net on the candidate function.
Copy-paste template — multidimensional catalogue + natives + mb_*
'Showcase', 'tarif' => 10000],
['nom' => 'Shop', 'tarif' => 25000],
];
$catalogue[] = ['nom' => 'Custom', 'tarif' => 50000];
echo count($catalogue); // 3
foreach ($catalogue as $prestation) {
echo htmlspecialchars($prestation['nom']) . ': ' . $prestation['tarif'] . "\n";
}
$tarifs = array_column($catalogue, 'tarif');
echo in_array(25000, $tarifs) ? 'Rate found' : 'Not found';
echo mb_strlen('Référencement'); // correctly counts accented characters
Catalogue in Constantine
Like Riad: list of name/rate associatives — the foreach display follows the exact shape of a future database result.
Possibly missing key
$prestation['promo'] ?? 'none': safe access avoids the warning when a row lacks the key.
Search or filter
in_array for "exists?", array_filter for "which ones?" — two natives instead of two home-made loops.
Accented text
French titles require it: mb_strlen/mb_substr to measure and truncate without cutting an accented character.
✓ Best practices
- Choose indexed (list) or associative (named data) according to the data's nature.
- Access keys safely (isset, ?? for missing keys).
- Look for a native function before writing a loop.
✗ Common pitfalls
- Accessing a missing key without checking (warning/error).
- Handling accented text with strlen/substr (bytes) instead of mb_*.
- Hand-rewriting what a native function does better.
Key takeaways
- ARRAYS are THE central PHP structure: INDEXED (numeric index, `$tab[0]`), ASSOCIATIVE (text key, `$tab['nom']`, everywhere), MULTIDIMENSIONAL (arrays inside arrays).
- PHP has HUNDREDS of native functions: arrays (count, in_array, array_map/filter/reduce, sort, implode/explode) and strings (strlen, str_replace, substr, trim, str_contains).
- REFLEX: do not reinvent what exists — before writing a loop, look for the native function (often more efficient). The official PHP docs are excellent, check them.
- Unicode caution: classic functions (strlen, substr) work on BYTES (a problem with accents/non-Latin characters in UTF-8); use MULTI-BYTE (mb_*) functions.
48h challenge — apply tomorrow
Restructure separate variables into an array (template above): replace one home-made loop with count/in_array/array_filter and one strlen on accented text with mb_strlen. Check the display. 25 minutes is enough.
- I choose indexed, associative or multidimensional according to the data.
- I use natives (count, in_array, array_map/filter, implode/explode).
- I handle Unicode with mb_* and access keys with safe ??.
Frequently asked questions
Indexed or associative arrays: when to use which, and how to use them well?
INDEXED array: access by numeric index — represents a LIST of same-nature elements (`$couleurs = ['red', 'green', 'blue']`), when order matters or you collect (`$tab[] = ...`). ASSOCIATIVE array: access by a meaningful TEXT key — represents STRUCTURED data (`$utilisateur = ['nom' => 'Alice', ...]`), for one entity (user, product, database row). Very frequent in PHP web (`$_POST`, database results). The COMBINATION (multidimensional) is everywhere: an INDEXED of ASSOCIATIVES = a list of entities, exactly a query result, iterated with foreach. Best practices: choose according to nature, name keys clearly, access safely (isset, `??`), iterate with foreach.
Why rely on PHP's native functions rather than coding everything yourself?
TIME SAVED (in_array in one call vs a loop), RELIABILITY (proven by millions of uses, edge cases handled), PERFORMANCE (implemented in C, fast), READABILITY (`array_filter($users, ...)` states intent), STANDARD (known to all). Categories: strings, arrays, dates, maths, files, validation. The reflex: BEFORE writing a loop, ask "does a native exist?" and check php.net. Reserve your code for your BUSINESS LOGIC.
What is PHP's central data structure?