Який в тебе масив — асоціативний чи індексований?
В PHP масив — це універсальний інструмент, який не вимагає від тебе визначати розмір, тип елементів чи навіть структуру ключів. Це з одного боку ніби і зручно, але з іншого — є проблемою.
Більшість мов програмування виділяють масиви (indexed arrays) і словники/мапи (associative arrays), а в PHP це одна й та ж сама структура: будь-який масив може стати асоціативним або нумерованим в залежності від ключів, які ти використовуєш:
$a = [1, 2, 3, 4, 5]; // індексований
$b = ['foo' => 6]; // асоціативний
$c = [
...$a,
...$b
]; // змішаний
Часто виникає потреба по-різному обробляти масиви в залежності від їх типу. Але PHP не дає такої базової можливості, бо він взагалі не розрізняє індексовані та асоціативні масиви, про що прямо написано в документації.
Чи допоможе array_is_list?
Можна подумати, що array_is_list може допомогти зʼясувати, хто є хто:
array_is_list($a); // true [0=>1, 1=>2, 2=>3, 3=>4, 4=>5]
array_is_list($b); // false [foo=>6]
array_is_list($c); // false [0=>1, 1=>2, 2=>3, 3=>4, 4=>5, foo=>6]
На перший погляд все добре, але ні.
Розширимо наш приклад: витягнемо з масиву $a тільки непарні числа.
$a2 = array_filter($a, fn($x) => $x % 2 !== 0); // 1,3,5
array_is_list($a2); // false бо 0=>1, 2=>3, 4=>5
Що сталося з масивом? Невже він став асоціативним?
Ні. Просто array_filter зберігає оригінальні ключі. І хоч це все ще числові ключі, але через “дірки” в індексації array_is_list повертає false.
Тобто PHP не ставить знак дорівнює між "нумерованим" та "індексованим" типами масивів.
Рядкові ключі — не гарантують “асоціативність”
Ще одна неприємність, яка може вас очікувати.
Багато хто вважає, що якщо в масиві ключ рядковий — все, це асоціативний масив. Але якщо ключ виглядає як число, PHP конвертує його в int. Наприклад, штрихкоди товарів:
$products = [
"0123456789052" => "Товар",
"8018075001428" => "Ще товар"
];
print_r(array_keys($products));
//Array
//(
// [0] => "0123456789052"
// [1] => 8018075001428 // -- рядок став числом
//)
Тому на ключі типу “рядок чи число” теж покладатися не можна.
Висновок
Я бачив багато коду, де масив використовують як list, а потім раптово додають рядковий ключ — і все, data integrity накрилась. Якщо твоя логіка дійсно залежить від того, який у тебе масив — перевіряй не
array_is_list, а реально структуру ключів (черезarray_keys,is_int,is_stringі т.д.). А ще краще — не лінуйся типізувати і перевіряти дані на вході, навіть якщо це PHP.
Вперше опубліковано в Telegram-каналі «Створений щоб помирати» 17.07.2025.