PHP: полный мануал с примерами, функциями и ООП
Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Дерево руководства
Глава 70 · От первого опыта к практике
Полный справочник функций массивов
Все 88 пунктов официальной категории Arrays: от первого элемента и преобразования до сравнений, сортировки, курсора и миграции удалённой each.
Массив → нужная операция → проверяемый результат
Выбрать товары и подготовить список для JSON
Фильтр оставляет ключи исходных ячеек. Перед передачей именно списка их нужно перенумеровать.
- 1[0 => Книга, 1 => Лампа, 2 => Стол]↓
Исходный список из трёх товаров.
- 2array_filter↓
Предположим, условию соответствуют только Книга и Стол.
- 3[0 => Книга, 2 => Стол]↓
Ключи сохранены; образовался пропуск 1.
- 4array_values↓
Получаем последовательные ключи 0 и 1 для договора списка.
- 5json_encode
API получает JSON-массив, а не объект с числовыми именами полей.
Перенумерация нужна для списка. Если ключи являются артикулами или ID, сохраняйте их и выберите формат словаря осознанно.
В ответе API, строках SQL и данных формы часто уже есть массив. Прежде чем выбирать функцию, назовите задачу: оставить доступные товары, сложить суммы, найти ключ или изменить очередь. Одинаковое слово «массив» не означает одинаковую форму: список хранит порядок, словарь — связь идентификатора со значением, таблица — вложенные записи.
- Создать обычные PHP-строки товаров p1 с остатком 2 и p2 с остатком 0
- Проверить форму строк и оставить положительный остаток
- Выдать список с одной строкой p1; формат ключей выбрать явно
Массив сам не знает, что поле stock означает остаток; это правило задаёт программа. Функции стандартной категории Arrays доступны в составе PHP; отдельный пакет для них не устанавливают. Новые функции всё же требуют своей версии: array_is_list — 8.1, array_all/any/find/find_key — 8.4, array_first/last — 8.5. each удалена в 8.0 и представлена для миграции.
Если синтаксис новый: переменная и присваивание → ключ, значение, чтение элемента → вызов, параметры, return → callback как переданная функция. Запись array $items в справочной сигнатуре описывает требуемый тип; она не создаёт массив. array ...$arrays означает несколько входов, &$array — изменение переданной переменной, : array — тип результата. Подробно: параметры и типы.
Выбрать по задаче и увидеть весь состав категории
Каждая ссылка ведёт к самостоятельной карточке с договором, схемой, первым опытом и применением. Ранее написанные карточки остаются на своих адресах в учебной главе «Массивы»; здесь собран общий вход. Сходное имя не означает одинаковое поведение: сначала сравните результат и правила ключей.
Псевдонимы входят в официальный состав: key_exists = array_key_exists, pos = current, sizeof = count. array и list — конструкции языка, поэтому обычные правила callable применимы к ним не полностью. Этот каталог охватывает 88 пунктов ref.array, включая устаревшую each. Он не является утверждением, что здесь уже написан весь PHP Manual.
Не перепутать новый массив, изменение и статус
Операции чтения часто возвращают новый массив; операции сортировки, очереди и указателя работают с переданной переменной. Присваивание статуса вместо данных — отдельная частая ошибка.
| Договор | Примеры |
|---|---|
| Возвращает новый массив | array_filter, array_map, array_slice, array_merge, array_replace, array_diff |
| Меняет массив и возвращает статус/размер | sort, usort, array_walk, array_push, array_unshift |
| Меняет массив и возвращает удалённое | array_splice, array_pop, array_shift |
| Только читает / меняет указатель | current и key читают; next, end меняют позицию, не удаляя данные. |
- original содержит [30,10,20]
- sorted получает значение массива; sort меняет sorted
- original остаётся прежним, статус равен true
<?php
$original = [30, 10, 20];
$sorted = $original;
$status = sort($sorted, SORT_NUMERIC);
echo json_encode($original), "
";
echo json_encode($sorted), "
";
var_dump($status);
Ожидаемый результат
[30,10,20]
[10,20,30]
bool(true)
В выводе JSON здесь только способ показать массив. Обычное копирование массива не клонирует находящиеся внутри объекты; ссылки на элементы также требуют отдельного понимания: ссылки и владение данными.
Все константы категории: какой функции они задают правило
Константа — именованное значение без знака $. Используйте имя, а не случайно запомненное число. Знак | объединяет только совместимые флаги; не все режимы разрешено смешивать.
| Константы | Назначение |
|---|---|
| CASE_LOWER / CASE_UPPER | array_change_key_case: нижний/верхний регистр ключей. С PHP 8.2 преобразование только ASCII. |
| SORT_ASC / SORT_DESC | array_multisort: направление предыдущей колонки. Это не аргументы направления для sort. |
| SORT_REGULAR | Обычные правила сравнения PHP; смешанные типы могут дать неожиданный предметный порядок. |
| SORT_NUMERIC | Сравнение числовых представлений. |
| SORT_STRING | Сравнение строковых представлений. Это также режим по умолчанию у array_unique. |
| SORT_LOCALE_STRING | Сравнение строк в текущей locale; результат зависит от окружения/setlocale. |
| SORT_NATURAL | Числовые фрагменты строк идут естественным порядком: item2 перед item10. |
| SORT_FLAG_CASE | Добавка через | к SORT_STRING или SORT_NATURAL; нечувствительность к ASCII-регистру с PHP 8.2. |
| ARRAY_FILTER_USE_KEY | array_filter: callback получает только ключ. |
| ARRAY_FILTER_USE_BOTH | array_filter: callback получает значение, затем ключ. Без режима — только значение. |
| COUNT_NORMAL / COUNT_RECURSIVE | count / sizeof: верхний уровень либо вложенные массивы с учётом контейнеров. |
| EXTR_OVERWRITE | extract по умолчанию перезаписывает существующее имя. |
| EXTR_SKIP | extract оставляет существующее имя нетронутым. |
| EXTR_PREFIX_SAME | При коллизии extract добавляет prefix и подчёркивание. |
| EXTR_PREFIX_ALL | extract добавляет prefix ко всем именам. |
| EXTR_PREFIX_INVALID | extract добавляет prefix только к недопустимым/числовым именам. |
| EXTR_IF_EXISTS | extract изменяет только уже существующие имена. |
| EXTR_PREFIX_IF_EXISTS | extract создаёт prefixed-имя только при наличии исходного имени. |
| EXTR_REFS | Дополнительный флаг extract: переменные связаны с элементами массива по ссылке. Может использоваться один или через | с основным режимом. |
Подробные отказы, префиксы и область применения — в extract. Отбор существующих имён не делает недоверенные значения безопасными. SORT_NATURAL и SORT_FLAG_CASE не перечислены как режимы array_unique; не переносите все флаги сортировки в любую функцию с параметром flags.
Полная таблица выбора сортировки и стабильность
У выбора сортировки четыре независимых вопроса: что сравнивается, сохраняются ли ключи, какое направление и как определено равенство. Все функции в этой таблице изменяют переданный массив. Результат true нельзя выдавать за отсортированный список.
| Функция | Сравнивает / сохраняет ключи | Порядок |
|---|---|---|
array_multisort | Значения нескольких колонок / Строковые да; числовые нет | Первый критерий, затем следующие |
asort | Значения / Да | Возрастание |
arsort | Значения / Да | Убывание |
krsort | Ключи / Да | Убывание |
ksort | Ключи / Да | Возрастание |
natcasesort | Значения / Да | Естественный без ASCII-регистра |
natsort | Значения / Да | Естественный с регистром |
rsort | Значения / Нет | Убывание |
shuffle | Значения / Нет | Случайный порядок |
sort | Значения / Нет | Возрастание |
uasort | Значения / Да | Свой компаратор |
uksort | Ключи / Да | Свой компаратор |
usort | Значения / Нет | Свой компаратор |
С PHP 8 сортировка стабильна: если два элемента равны по всем её критериям, их исходный взаимный порядок сохраняется. Это свойство не относится к случайному shuffle как к сравнению равных значений и не означает, что произвольный порядок входа уже подходит пользователю.
- Заказы A и B имеют приоритет 1; C — 0
- Сравниваем только приоритет
- C перемещается вперёд, A остаётся перед B
<?php
$orders = [['id' => 'A', 'priority' => 1], ['id' => 'B', 'priority' => 1], ['id' => 'C', 'priority' => 0]];
usort($orders, function ($a, $b) { return $a['priority'] <=> $b['priority']; });
echo implode(',', array_column($orders, 'id')), "
";
Ожидаемый результат
C,A,B
function(...) передаёт сравнение, <=> возвращает -1/0/1. Когда приоритеты равны, callback отдаёт 0, не выбирая порядок по ID. Второй критерий добавляют явно, если он нужен задаче.
Ключ, значение, глубина и форма результата
Разность diff сохраняет элементы первого массива, отсутствующие во всех последующих. intersect требует совпадение в каждом последующем. Порядок аргументов важен, а количество повторов — не вычитание математических мультимножеств.
| Семейство | Правило |
|---|---|
| diff / intersect | Встроенное равенство строковых представлений значений; ключи сравниваемых массивов не важны. |
| *_assoc | Должны совпасть ключ и значение одной пары. |
| *_key | Сравниваются только ключи, данные под ними могут различаться. |
| *_uassoc / *_ukey | Пользовательское сравнение ключей. |
| array_udiff / array_uintersect | Пользовательское сравнение значений. |
| array_udiff_uassoc / array_uintersect_uassoc | Два callback: сначала значения, затем ключи. |
Встроенное равенство значений этих diff/intersect — не режим === по исходным типам. Число 1 и строка "1" совпадут. Для строгой схемы сначала проверьте типы; для собственного правила нужен компаратор с целым отрицательным/нулевым/положительным результатом. Ни diff, ни intersect не спускаются по всему JSON-дереву автоматически. Как извлечь и проверить вложенные данные; как строить явный обход.
Мини-упражнение: есть [10 => "A", 20 => "B"] и [30 => "A"]. До запуска предскажите разность по значениям, разность по ключам и разность по парам. Затем откройте три карточки и объясните, почему ответы разные.
Стоимость, безопасные границы и последовательный маршрут
Операция над готовым массивом не делает источник потоковым. array_chunk и slice полезны для уже имеющихся небольших данных, но не отменяют загрузку миллиона строк до этого. Повторные merge с растущим результатом, shift больших очередей и дорогие callback сортировки требуют отдельного измерения на вашей нагрузке.
- Нужен первый ответ: array_find/any/all могут завершить проверку раньше; полный filter создаёт весь результат.
- Нужно много проверок уникального ID: заранее построенный словарь может заменить повторные линейные поиски; учтите преобразование ключей и память.
- Нужно пройти данные один раз: foreach часто яснее цепочки временных map/filter/values.
- Нужна непредсказуемость: array_rand/shuffle не подходят для секретов; выбирайте Randomizer с Secure либо random_int/random_bytes.
- Нужны независимые объекты: копирование массива и array_fill одним объектом не клонируют экземпляры.
Маршрут после базы: array_filter → array_map → array_column → array_reduce → array_replace_recursive → usort. Практические продолжения: приём и проверка формы, интеграция с API, измерение стоимости вместо догадок.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
arrayСобрать несколько связанных значений в одно: список товаров или запись с именованными полями.
PHP 4+ · standard
array(key => value, ...) → array; короткая форма: [key => value, ...]Собрать несколько связанных значений в одно: список товаров или запись с именованными полями.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| Элементы | Между скобками перечисляются значения через запятую. В key => value левая часть задаёт ключ, правая — значение. |
| Ключ | Целое число или строка. Без явного ключа PHP выбирает следующий целочисленный индекс; в пустом массиве первый — 0. |
| Повтор ключа | Позднее значение заменяет прежнее. Это словарь, а не место для нескольких значений под одним ключом. |
| Возврат | Новый массив в заданном порядке; array() и [] без элементов создают пустой массив. |
| Отказ и диагностика | Недопустимый тип ключа, например массив, вызывает TypeError. Преобразования допустимых ключей могут создать незаметную коллизию. |
Это конструкция языка, а не обычная функция: её нельзя вызвать через строковое имя функции. array(...) и [...] — две записи одного значения; короткая форма доступна с PHP 5.4. = сохраняет массив в переменной, [0] справа читает элемент с ключом 0.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: ключ, значение и порядок массива.
- Создать [чай, кофе] с ключами 0 и 1.
- Прочитать обе позиции для подписи.
- Заменить drinks[1] на воду и прочитать новый заказ.
<?php
$drinks = array('чай', 'кофе');
$firstDrink = $drinks[0];
$secondDrink = $drinks[1];
echo 'В заказе: ', $firstDrink, ' и ', $secondDrink, ".\n";
$drinks[1] = 'вода';
echo 'После изменения: ', $drinks[0], ' и ', $drinks[1], ".\n";
Ожидаемый результат
В заказе: чай и кофе.
После изменения: чай и вода.
Array — языковая конструкция создания массива. Круглые скобки ограничивают значения, запятая отделяет их; присваивание сохраняет весь массив в drinks. Первый автоматически назначенный ключ 0, следующий 1. Квадратные скобки после переменной читают или изменяют одну ячейку. Короткая запись ['чай', 'кофе'] создаёт тот же массив. Изменение ячейки не меняет ранее прочитанную secondDrink: это отдельное строковое значение.
<?php
$product = [
'sku' => '0041',
'stock' => 2,
'stock' => 0,
];
echo $product['sku'], ':', $product['stock'], "\n";
$queue = [5 => 'paid', 'packed'];
echo json_encode($queue), "\n";
Ожидаемый результат
0041:0
{"5":"paid","6":"packed"}
Второй stock заменил первый; ноль сохранён как значение. После явного ключа 5 автоматический ключ равен 6. Последняя запятая разрешена и удобна в многострочной записи.
Нюансы и выбор. Вложенный массив создаётся теми же скобками, но уровень вложенности не добавляет проверку схемы. Строка-ключ "8" обычно становится int 8; "08" сохраняет строковую форму. Не путайте максимальный числовой ключ с количеством элементов. Для отрицательных автоматических ключей есть изменение PHP 8.3; оно подробно разобрано в правилах ключей и добавления. Массивы из результата SQL или json_decode используют те же правила, что литерал.
Сравните: list, array_fill, range, count. Выбрать операцию по задаче.
listРазложить строку отчёта в несколько понятных переменных одним присваиванием.
PHP 4+ · standard
list($first, $second, ...) = $array; также [$first, $second] = $arrayРазложить строку отчёта в несколько понятных переменных одним присваиванием.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| Цели слева | Переменные, которым присваиваются элементы. Пустое место между запятыми пропускает соответствующий индекс. Полностью пустой list() недопустим. |
| Ключи | Без явных ключей выбираются 0,1,…, а не первые элементы произвольного словаря. С PHP 7.1 можно указать ключ => переменная. Не смешивайте явную и неявную форму в одном списке. |
| Правая часть | Массив или объект ArrayAccess. Это источник значений, а не переменные, которые нужно создать по динамическим именам. |
| Возврат | Присваивает элементы целевым переменным; значение всего выражения присваивания — исходный массив. |
| Отказ и диагностика | Отсутствующий ключ даёт E_WARNING и null в PHP 8. Скаляр даёт null целям; с PHP 8.5 ненулевой не-массив дополнительно предупреждает. Обычный объект без ArrayAccess вызывает Error. |
list($sku, $stock) = $row; читает row[0] и row[1]. Запись в квадратных скобках — тот же разбор, не создание нового списка слева. Сначала убедитесь, что строка имеет нужную форму.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: ключ, значение и порядок массива.
- В строке 0→0041, 1→3.
- List создаёт sku=0041 и quantity=3.
- Собрать из этих переменных понятную строку накладной.
<?php
$row = ['0041', 3];
list($sku, $quantity) = $row;
$label = 'Артикул ' . $sku . ': ' . $quantity . ' упаковки';
echo $label, "\n";
[$sameSku, $sameQuantity] = $row;
echo 'Короткая запись: ', $sameSku, ', ', $sameQuantity, "\n";
Ожидаемый результат
Артикул 0041: 3 упаковки
Короткая запись: 0041, 3
Сначала PHP вычисляет правый массив row. List присваивает элемент с ключом 0 переменной sku, с ключом 1 переменной quantity. Это распаковка значений, а не перебор и не создание функции. Строковый артикул сохраняет начальные нули. Точка соединяет части подписи. Короткая форма слева [] делает то же. Форма строки заранее известна; отсутствие ключа потребовало бы проверки до распаковки.
<?php
$row = ['stock' => 0, 'sku' => '0072'];
['sku' => $sku, 'stock' => $stock] = $row;
echo $sku, ':', $stock, "\n";
$slots = [4, 9];
[&$first] = $slots;
$first = 7;
unset($first);
echo json_encode($slots), "\n";
Ожидаемый результат
0072:0
[7,9]
Именованные ключи появились в PHP 7.1, ссылки в распаковке — в 7.3. & связал first с элементом slots[0]; unset разорвал связь. Для обычного чтения ссылка не нужна.
<?php
set_error_handler(function ($severity, $message) {
echo $severity === E_WARNING ? "Предупреждение\n" : "Другая диагностика\n";
return true;
});
try {
[$sku, $stock] = ['0041'];
var_dump($stock);
} finally {
restore_error_handler();
}
Ожидаемый результат
Предупреждение
NULL
Обработчик нужен только для наблюдения за диагностикой этого опыта и восстанавливается. В реальном импорте до распаковки проверяют наличие обязательной колонки; null не является корректным остатком.
Нюансы и выбор. Допускается вложенная распаковка и использование в foreach. Она выбирает значения, но не проверяет их типы и не ищет похожие имена. ArrayAccess означает специальный объект с договором чтения по ключу; обычный stdClass им не является. Ссылки и вложенность требуют внимательного владения данными; явные обращения $row["sku"] часто яснее для одной колонки. Не используйте трюки с порядком присваивания нескольким $array[] как переносимый договор между старыми версиями PHP.
Сравните: array, array_column, extract. Выбрать операцию по задаче.
rangeСоздать ограниченную последовательность: номера страниц, интервалы измерения или ASCII-метки.
PHP 4+ · standard
range(string|int|float $start, string|int|float $end, int|float $step = 1): arrayСоздать ограниченную последовательность: номера страниц, интервалы измерения или ASCII-метки.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| start / end | Начало и последняя возможная граница. Направление выбирается по их соотношению; end входит только если шаг попадает точно. |
| step | Расстояние между соседними значениями. Ноль запрещён; отрицательный шаг допустим для убывания. Целочисленный float вроде 2.0 трактуется как int с PHP 8.3. |
| Строковые границы | Для однобайтовых строк и целого шага получается последовательность байтов. Числовые строки длиной больше байта требуют отдельного внимания к типу результата (опыт ниже). Это не генератор букв Unicode. |
| Возврат | Готовый массив int, float или однобайтовых строк с числовыми ключами с нуля. |
| Отказ и диагностика | ValueError: шаг 0, неконечные числовые значения (бесконечность INF или не-число NAN), отрицательный шаг для возрастания; в PHP 8.5.11 также шаг больше расстояния между различными числовыми границами. Равные границы допускают один элемент. С PHP 8.3 ужесточены типы границ; массив/объект/ресурс дают TypeError. Неподходящие строковые режимы могут предупреждать. |
В range(1, 5, 2) числа означают начало 1, границу 5 и шаг 2. Функция сразу создаёт все элементы; цикл или генератор позволяет выдавать их постепенно.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Начало 1; шаг 2; верхняя граница 5.
- Получаются значения 1, затем 3, затем 5.
- Следующий кандидат 7 не входит; результат [1,3,5].
<?php
echo json_encode(range(1, 5, 2)), "\n";
echo json_encode(range(5, 1, 2)), "\n";
echo json_encode(range(1, 6, 2)), "\n";
Ожидаемый результат
[1,3,5]
[5,3,1]
[1,3,5]
Положительный размер шага подходит и убывающей последовательности. Последняя граница 6 не добавляется искусственно.
<?php
$sections = range('A', 'C');
echo implode(',', $sections), "\n";
$pages = range(1, 3);
foreach ($pages as $page) {
echo '/catalog?page=', $page, "\n";
}
Ожидаемый результат
A,B,C
/catalog?page=1
/catalog?page=2
/catalog?page=3
Первая последовательность состоит из ASCII-байтов. Для русских букв или сложных Unicode-символов такой диапазон не подходит. URL здесь только выводятся, сетевых запросов нет.
<?php
foreach ([0, -1] as $step) {
try {
range(1, 3, $step);
} catch (ValueError) {
echo "Неверный шаг\n";
}
}
echo json_encode(range(3, 1, -1)), "\n";
Ожидаемый результат
Неверный шаг
Неверный шаг
[3,2,1]
Для отрицательного шага возрастания ожидаемое поведение относится к PHP 8.3+. Не перехватывайте ошибку настройки, чтобы выдавать внешнему клиенту ложный успешный пустой результат.
<?php
echo json_encode(range('1', '3')), "\n";
echo json_encode(range('10', '12')), "\n";
echo json_encode(range(10, 12)), "\n";
try { range(1, 2, 3); }
catch (ValueError) { echo "Шаг больше диапазона\n"; }
Ожидаемый результат
["1","2","3"]
[10,11,12]
[10,11,12]
Шаг больше диапазона
Проверено на PHP 8.5.11: однобайтовые числовые строки образуют строки-байты, многобайтовые числовые строки здесь образуют числа. Краткая формулировка Manual о двух строках не описывает этот частный случай достаточно точно; для числового договора задавайте проверенные int/float явно.
Нюансы и выбор. Память растёт с количеством созданных элементов: не передавайте пользовательский верхний предел без ограничения. С PHP 8.3 изменены правила строковых границ; нельзя считать, что любые две строки всегда дадут тот же тип элементов. Для числовых данных сначала явно проверьте и задайте числовой тип. Пустая строка предупреждает и трактуется как 0; многобайтовая нечисловая граница, смесь числа с приводимой строкой и нечисловые строки с дробным шагом тоже могут предупреждать. Float-диапазон использует двоичную арифметику, поэтому денежные шаги лучше задавать целыми копейками.
Сравните: array_fill, array_fill_keys, array_map. Выбрать операцию по задаче.
array_fillЗаранее подготовить одинаковые начальные значения: например четыре свободных места в расписании.
PHP 4.2+ · standard
array_fill(int $start_index, int $count, mixed $value): arrayЗаранее подготовить одинаковые начальные значения: например четыре свободных места в расписании.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| start_index | Первый целочисленный ключ. Последующие идут по одному, включая отрицательные в PHP 8. |
| count | Количество элементов, от 0 до 2147483647. Это предел типа API, не обещание доступной памяти. |
| value | Значение для каждого элемента. Один переданный объект остаётся тем же объектом во всех ячейках. |
| Возврат | Новый заполненный массив; count=0 даёт []. Исходные переменные не заменяются. |
| Отказ и диагностика | В PHP 8 недопустимый count вызывает ValueError; до PHP 8 были warning и false. Возможна нехватка памяти при чрезмерном размере. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Начать с ключа 9 и создать три одинаковых значения.
- Записать имя в ячейку 10.
- Вывести все часы, включая два свободных.
<?php
$slots = array_fill(9, 3, 'свободно');
$slots[10] = 'записана Анна';
foreach ($slots as $hour => $state) {
echo $hour, ':00 — ', $state, "\n";
}
Ожидаемый результат
9:00 — свободно
10:00 — записана Анна
11:00 — свободно
Аргумент 9 — начальный ключ, 3 — число элементов, а не конечный час. Сначала возвращён массив с ключами 9, 10, 11 и одинаковой строкой «свободно». Затем меняется лишь значение ключа 10. Foreach берёт каждый час и его состояние для экрана расписания. Функция не знает календаря: интервалы здесь целые часы одного дня; реальное расписание с датами потребовало бы иной модели.
<?php
echo json_encode(array_fill(-2, 3, 0)), "\n";
echo json_encode(array_fill(0, 0, 'free')), "\n";
try {
array_fill(0, -1, 'free');
} catch (ValueError) {
echo "Количество не может быть отрицательным\n";
}
Ожидаемый результат
{"-2":0,"-1":0,"0":0}
[]
Количество не может быть отрицательным
В PHP 8 после −2 идёт −1, затем 0. В версиях до 8.0 после первого отрицательного ключа переходили к 0.
<?php
$prototype = (object) ['stock' => 0];
$rows = array_fill(0, 2, $prototype);
$rows[0]->stock = 3;
echo $rows[1]->stock, "\n";
Ожидаемый результат
3
(object) создаёт простой объект, ->stock обращается к его свойству. Обе ячейки держат один экземпляр. Для независимых объектов создавайте каждый отдельно; array_fill не является фабрикой и не клонирует значение.
Нюансы и выбор. Для списков обычно начинайте с 0. Если передать один объект, его состояние будет общим; это не относится к простой замене строковых ячеек первого опыта. При большом числе строк разумнее создавать данные порциями по мере необходимости.
Сравните: array_fill_keys, range, array_pad. Выбрать операцию по задаче.
array_fill_keysПодготовить словарь с известными ключами, например счётчики заказов по статусам.
PHP 5.2+ · standard
array_fill_keys(array $keys, mixed $value): arrayПодготовить словарь с известными ключами, например счётчики заказов по статусам.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| keys | Значения массива становятся ключами результата; исходные ключи этого массива не используются. |
| value | Одинаковое стартовое значение для всех ключей. Объекты не клонируются. |
| Возврат | Новый словарь. Повторяющиеся или совпавшие после преобразования ключи объединяются. |
| Отказ и диагностика | Нужен массив keys. Необычные типы ключей преобразуются в строки и могут дать диагностику или Error при невозможности строкового преобразования; передавайте заранее проверенные int/string. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Создать new=0, paid=0, sent=0.
- Пройти paid, new, paid: получить 1,2,0.
- Вывести полный отчёт, включая sent=0.
<?php
$counts = array_fill_keys(['new', 'paid', 'sent'], 0);
$today = ['paid', 'new', 'paid'];
foreach ($today as $status) {
$counts[$status]++;
}
foreach ($counts as $status => $quantity) {
echo $status, ': ', $quantity, ' заказа', "\n";
}
Ожидаемый результат
new: 1 заказа
paid: 2 заказа
sent: 0 заказа
В первом аргументе значения new/paid/sent становятся ключами. Второй аргумент 0 задаёт начальное количество. Возвращённый словарь записан в counts; каждый ++ увеличивает выбранный счётчик на 1. Порядок отчёта определяется списком разрешённых статусов. Today здесь содержит только заранее проверенные коды: неизвестный код потребовал бы отдельной обработки, а не чтения отсутствующего счётчика.
<?php
$allowed = array_fill_keys(['A', 'B', 'A'], true);
var_dump(isset($allowed['B']));
var_dump(isset($allowed['C']));
echo count($allowed), "\n";
Ожидаемый результат
bool(true)
bool(false)
2
Повтор A не создаёт третьего элемента. Здесь значения всегда true, поэтому isset подходит; для словаря с null различайте отсутствие ключа через array_key_exists.
Нюансы и выбор. Это не проверка типа ключей. Числовые строки могут преобразоваться в int и совпасть с числовым ключом. Набор для множества повторных проверок может быть удобнее повторного сканирования in_array, но требует отдельной памяти и согласованной политики ключей.
Сравните: array_fill, array_combine, array_key_exists, in_array. Выбрать операцию по задаче.
array_combineСвязать заголовки и одну строку данных: превратить колонки CSV в именованные поля.
PHP 5+ · standard
array_combine(array $keys, array $values): arrayСвязать заголовки и одну строку данных: превратить колонки CSV в именованные поля.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| keys | Значения первого массива становятся ключами результата в порядке обхода. |
| values | Значения второго массива становятся соответствующими значениями, тоже по порядку. Ключи исходных массивов не сопоставляются. |
| Возврат | Новый массив ключ → значение. Два пустых массива дают []; одинаковые ключи оставляют позднее значение. |
| Отказ и диагностика | Разное число элементов в PHP 8 вызывает ValueError; ранее выдавались warning и false. Ключи должны быть осмысленными int/string; преобразование прочих типов может предупреждать или завершиться Error. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: параметры и результат вызова.
- Три имени и три значения идут в соответствующем порядке.
- Combine создаёт sku/quantity/priceKopecks.
- Прочитать количество и цену, вычислить 450 копеек.
<?php
$headers = ['sku', 'quantity', 'priceKopecks'];
$cells = ['0041', 3, 150];
$row = array_combine($headers, $cells);
$lineTotal = $row['quantity'] * $row['priceKopecks'];
echo 'Товар ', $row['sku'], ': ', $row['quantity'], ' × ', $row['priceKopecks'], ' = ', $lineTotal, ' коп.', "\n";
Ожидаемый результат
Товар 0041: 3 × 150 = 450 коп.
Первое имя sku связывается с первым значением 0041, затем quantity с 3 и priceKopecks со 150. Return функции — новый именованный массив row. После этого программа обращается к понятным именам колонок и получает 450. Combine не преобразует CSV-текст в числа и не проверяет цены; в этом минимальном опыте значения уже имеют нужные типы.
<?php
function mapImportRow(array $headers, array $cells): array
{
if (count($headers) !== count($cells)) {
throw new UnexpectedValueException('Число колонок не совпало');
}
if (count(array_unique($headers)) !== count($headers)) {
throw new UnexpectedValueException('Повтор заголовка');
}
return array_combine($headers, $cells);
}
try {
mapImportRow(['sku', 'stock'], ['0041']);
} catch (UnexpectedValueException $error) {
echo $error->getMessage(), "\n";
}
echo json_encode(array_combine(['sku', 'sku'], ['A', 'B'])), "\n";
Ожидаемый результат
Число колонок не совпало
{"sku":"B"}
В этом примере заголовки уже непустые строки из известной схемы. Обёртка даёт прикладное сообщение и предотвращает потерю дублирующейся колонки. Прямой второй вызов специально показывает позднюю замену.
Нюансы и выбор. Перед этой операцией проверьте допустимые имена колонок и их уникальность. После неё остаётся преобразование и проверка значений: текст из CSV не станет автоматически корректной ценой. Нельзя считать успешный combine доказательством полного совпадения формата поставщика.
Сравните: array_column, array_fill_keys, array_merge. Выбрать операцию по задаче.
compactСобрать уже существующие локальные переменные в массив для передачи шаблону.
PHP 4+ · standard
compact(array|string $var_name, array|string ...$var_names): arrayСобрать уже существующие локальные переменные в массив для передачи шаблону.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| var_name / var_names | Строки с именами переменных без $, либо массивы таких имён. Вложенные массивы имён обходятся рекурсивно. |
| Область поиска | Текущая область переменных точки вызова. compact не загружает отсутствующие глобальные переменные внутрь функции. |
| Возврат | Массив имя переменной → её значение. Необъявленные имена пропускаются с диагностикой. |
| Отказ и диагностика | В PHP 8 отсутствующая переменная вызывает E_WARNING; в 7.3–7.x это был E_NOTICE, раньше — молчаливый пропуск. Не путайте отсутствующую переменную с существующей переменной со значением null. |
compact("title") получает имя, ищет локальную $title и создаёт поле title. В compact($title) содержимое title само стало бы искомым именем — это другая операция.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: параметры и результат вызова.
- В текущей области title=Каталог и total=2.
- По двум именам собрать новый массив view.
- Из его полей вывести подпись; позднее изменение title её не меняет.
<?php
$title = 'Каталог';
$total = 2;
$view = compact('title', 'total');
echo $view['title'], ': найдено ', $view['total'], ' товара', "\n";
$title = 'Архив';
echo 'Сохранённый заголовок: ', $view['title'], "\n";
Ожидаемый результат
Каталог: найдено 2 товара
Сохранённый заголовок: Каталог
Строка title без знака $ сообщает имя искомой местной переменной. Compact прочитал её нынешнее значение «Каталог», добавил total=2 и вернул массив view. Echo затем читает поля из view. Присваивание «Архив» исходной строковой переменной не меняет уже собранное поле. Явная альтернатива: ['title' => $title, 'total' => $total].
<?php
function viewData(): array
{
$title = 'Orders';
$notice = null;
return compact(['title', ['notice']]);
}
echo json_encode(viewData()), "\n";
Ожидаемый результат
{"title":"Orders","notice":null}
Вложен именно список имён, а результат остаётся плоским словарём. notice существует, поэтому null сохраняется. return передаёт массив вызывающему коду.
Нюансы и выбор. Связь со строковыми именами менее заметна инструментам переименования, чем ["title" => $title]. Не передавайте произвольный список имён от посетителя: он не должен выбирать, какие локальные данные уйдут наружу. Особенность dynamic variable lookup внутри функций мешает использовать так имена суперглобальных массивов; явно выбирайте необходимые безопасные поля.
Сравните: extract, array, array_combine. Выбрать операцию по задаче.
extractСоздать локальные переменные из заранее доверенного массива — в основном для границы старого шаблонизатора.
PHP 4+ · standard
extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""): intСоздать локальные переменные из заранее доверенного массива — в основном для границы старого шаблонизатора.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Ассоциативный массив: ключ становится именем переменной, значение — её содержимым. Допустимость имени проверяется, но безопасность и тип значения не проверяются. |
| EXTR_OVERWRITE / EXTR_SKIP | По умолчанию существующее имя перезаписывается. SKIP сохраняет уже существующую переменную при коллизии. |
| EXTR_PREFIX_SAME / ALL / INVALID | Добавить prefix только при коллизии, ко всем именам либо к неверным/числовым именам. Итог всё равно должен быть допустимым именем переменной. |
| EXTR_IF_EXISTS / EXTR_PREFIX_IF_EXISTS | Изменить лишь уже существующие имена либо создать их варианты с префиксом. Это фильтрация имён, а не проверка входных значений. |
| EXTR_REFS | Добавочный флаг через | создаёт связи с элементами исходного массива. Изменение переменной меняет элемент. |
| prefix | Нужен для PREFIX-режимов. Между ним и ключом автоматически вставляется _. Для числовых ключей обычно требуется PREFIX_ALL или PREFIX_INVALID. |
| Возврат | Количество действительно импортированных переменных. Возвращается число, а не исходный или изменённый массив. |
| Отказ и диагностика | Неверные значения flags/prefix могут вызвать ValueError. Недопустимые имена, которые не удалось исправить разрешённым префиксом, не импортируются. По ссылке передавайте переменную массива, а не результат выражения. |
extract изменяет текущую область переменных. Именно поэтому нельзя распаковывать им напрямую $_GET, $_POST или ответ чужого API. В новом коде явные обращения к полям или list с перечисленными ключами обычно делают зависимость понятнее.
- Title уже существует: Каталог.
- SKIP пропускает title и создаёт stock=0.
- Прочитать переменные; отдельно вывести возвращённое число 1.
<?php
$title = 'Каталог';
$view = ['title' => 'Склад', 'stock' => 0];
$created = extract($view, EXTR_SKIP);
echo 'Заголовок: ', $title, "\n";
echo 'Остаток: ', $stock, ' шт.', "\n";
echo 'Создано переменных: ', $created, "\n";
Ожидаемый результат
Заголовок: Каталог
Остаток: 0 шт.
Создано переменных: 1
EXTR_SKIP — именованная константа режима: существующий title сохраняется. Ключ stock создаёт новую местную переменную $stock со значением 0. Сам вызов возвращает 1 в created, потому что импортировано одно имя. Число не содержит данные шаблона: они уже записаны в title/stock. Доверенный view создан рядом; в новом шаблоне явное $view['stock'] обычно делает зависимость понятнее.
<?php
$data = ['sku' => '0041', 0 => 'first'];
$created = extract($data, EXTR_PREFIX_ALL, 'view');
echo $view_sku, ':', $view_0, ':', $created, "\n";
Ожидаемый результат
0041:first:2
view_0 — допустимое имя, хотя исходный ключ числовой. Префикс даёт различимые имена, но не заменяет разрешённый список полей.
<?php
$data = ['stock' => 2];
extract($data, EXTR_PREFIX_ALL | EXTR_REFS, 'view');
$view_stock = 3;
unset($view_stock);
echo $data['stock'], "\n";
Ожидаемый результат
3
EXTR_REFS — явное изменение договора владения. unset разрывает локальную связь; значение массива уже изменилось. Для обычного вывода шаблона такая связь не нужна.
Нюансы и выбор. EXTR_IF_EXISTS не проверяет значение и может перезаписать важный локальный флаг. EXTR_SKIP тоже разрешает создание новых имён. Для шаблона ограничьте отдельной функцией область видимости, заранее сформируйте данные и перечислите разрешённые поля. Наличие этой функции в полном справочнике не означает рекомендацию массовой распаковки пользовательского ввода.
Сравните: compact, list, array_intersect_key. Выбрать операцию по задаче.
array_allПроверить, что каждый элемент подходит: например все выбранные товары доступны.
PHP 8.4+ · standard
array_all(array $array, callable $callback): boolДля следующих четырёх функций нужен PHP 8.4+. Callback принимает значение и ключ и возвращает bool; all/any возвращают общий bool, find — выбранное значение, find_key — его ключ. Важно заранее решить, какая из этих четырёх форм результата нужна дальше.
Проверить, что каждый элемент подходит: например все выбранные товары доступны.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив, который проверяется в его текущем порядке. |
| callback | Проверка callback(mixed $value, mixed $key): bool. Возвращайте осмысленный bool; передаются значение и ключ. |
| Возврат | true/false; пустой массив даёт true. |
| Отказ и диагностика | Неверный тип массива или невызываемый callback даёт TypeError. Исключение callback передаётся вызывающему коду; оно не является результатом false/null. |
Callback — функция, переданная другой функции. Здесь PHP вызывает её для очередного элемента: первый параметр получает значение, второй — ключ. function ($stock, $sku) { return $stock > 0; } объявляет такую проверку; return отдаёт bool. Короткая fn(...) => выражение автоматически возвращает результат одного выражения.
Для этого примера: передача функции как значения.
- stocks: A=2, B=0, C=4.
- Callback для A возвращает true, для B — false.
- Проверка останавливается; C не посещается, общий результат false.
<?php
$stocks = ['A' => 2, 'B' => 0, 'C' => 4];
$ready = array_all($stocks, function ($stock, $sku) {
echo $sku, "\n";
return $stock > 0;
});
var_dump($ready);
Ожидаемый результат
A
B
bool(false)
Обход идёт по порядку массива и заканчивается, как только общий ответ уже известен.
<?php
// PHP 8.4+.
$cart = [['sku' => 'A', 'quantity' => 1], ['sku' => 'B', 'quantity' => 2]];
$valid = $cart !== [] && array_all($cart, function ($row, $key) {
return is_int($row['quantity']) && $row['quantity'] > 0;
});
if ($valid) {
echo "Корзина принята\n";
foreach ($cart as $row) {
echo $row['sku'], ': ', $row['quantity'], ' шт.', "\n";
}
}
$emptyPassesRule = array_all([], function ($value, $key) { return false; });
echo 'Правило каждого элемента для пустого массива: ', $emptyPassesRule ? 'выполнено' : 'нарушено', "\n";
Ожидаемый результат
Корзина принята
A: 1 шт.
B: 2 шт.
Правило каждого элемента для пустого массива: выполнено
Callback вернул true для количества 1 и 2; all вернул true, отдельная проверка непустоты тоже true. Общий valid разрешил показать готовый состав. У пустого массива нет нарушителя, поэтому all вернул true, даже не вызывая всегда ложный callback. Форма строк и наличие quantity здесь заранее известны; на внешнем входе их проверяют отдельно.
Нюансы и выбор. Для пустого массива результат true: нет элемента, нарушающего условие. Поэтому требование «корзина не пуста и каждая позиция корректна» состоит из двух проверок. Здесь форма строк уже известна; реальный API сначала проверяют на обязательные ключи. Для PHP 8.2/8.3 тот же договор выражается foreach с ранним return из функции; не стройте array_filter всех элементов, если нужен только первый ответ. Число вызовов callback зависит от места решающего элемента. Не меняйте проверяемый массив из callback и не прячьте в проверке отправку запросов.
Сравните: array_any, array_find, array_find_key, array_filter. Выбрать операцию по задаче.
array_anyУзнать, есть ли хотя бы один подходящий элемент: например доступный склад.
PHP 8.4+ · standard
array_any(array $array, callable $callback): boolУзнать, есть ли хотя бы один подходящий элемент: например доступный склад.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив, который проверяется в его текущем порядке. |
| callback | Проверка callback(mixed $value, mixed $key): bool. Возвращайте осмысленный bool; передаются значение и ключ. |
| Возврат | true/false; пустой массив даёт false. |
| Отказ и диагностика | Неверный тип массива или невызываемый callback даёт TypeError. Исключение callback передаётся вызывающему коду; оно не является результатом false/null. |
Callback — функция, переданная другой функции. Здесь PHP вызывает её для очередного элемента: первый параметр получает значение, второй — ключ. function ($stock, $sku) { return $stock > 0; } объявляет такую проверку; return отдаёт bool. Короткая fn(...) => выражение автоматически возвращает результат одного выражения.
Для этого примера: передача функции как значения.
- stocks: north=0, south=2, west=5.
- Callback для north ложен, для south истинен.
- Вернуть true; west для ответа уже не нужен.
<?php
$stocks = ['north' => 0, 'south' => 2, 'west' => 5];
var_dump(array_any($stocks, function ($stock, $warehouse) {
echo $warehouse, "\n";
return $stock > 0;
}));
Ожидаемый результат
north
south
bool(true)
Обход идёт по порядку массива и заканчивается, как только общий ответ уже известен.
<?php
// PHP 8.4+.
$orders = [['id' => 41, 'late' => false], ['id' => 42, 'late' => true]];
$hasLate = array_any($orders, function ($order, $key) {
return $order['late'] === true;
});
if ($hasLate) {
echo "Показать предупреждение: есть просроченные заказы\n";
}
$hasInEmptyList = array_any([], function ($value, $key) { return true; });
if (!$hasInEmptyList) {
echo "В пустом списке подходящих заказов нет\n";
}
Ожидаемый результат
Показать предупреждение: есть просроченные заказы
В пустом списке подходящих заказов нет
Callback отклоняет заказ 41 и принимает 42. Any возвращает true в hasLate; это разрешает общее предупреждение, но не возвращает запись заказа 42. Для неё нужна find. Пустой вход возвращает false, не вызывая callback.
Нюансы и выбор. Пустой массив даёт false: подходящего элемента нет. Метод нужен для ответа да/нет; чтобы получить сам просроченный заказ, используйте array_find. Для PHP 8.2/8.3 тот же договор выражается foreach с ранним return из функции; не стройте array_filter всех элементов, если нужен только первый ответ. Число вызовов callback зависит от места решающего элемента. Не меняйте проверяемый массив из callback и не прячьте в проверке отправку запросов.
Сравните: array_all, array_find, array_find_key, array_filter. Выбрать операцию по задаче.
array_findПолучить первое подходящее значение, например товар с ненулевым остатком.
PHP 8.4+ · standard
array_find(array $array, callable $callback): mixedПолучить первое подходящее значение, например товар с ненулевым остатком.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив, который проверяется в его текущем порядке. |
| callback | Проверка callback(mixed $value, mixed $key): bool. Возвращайте осмысленный bool; передаются значение и ключ. |
| Возврат | Первое подходящее значение; null, если совпадения нет. |
| Отказ и диагностика | Неверный тип массива или невызываемый callback даёт TypeError. Исключение callback передаётся вызывающему коду; оно не является результатом false/null. |
Callback — функция, переданная другой функции. Здесь PHP вызывает её для очередного элемента: первый параметр получает значение, второй — ключ. function ($stock, $sku) { return $stock > 0; } объявляет такую проверку; return отдаёт bool. Короткая fn(...) => выражение автоматически возвращает результат одного выражения.
Для этого примера: передача функции как значения.
- stocks: A=0, B=2, C=4.
- Callback отклоняет A и принимает B.
- Возвращается значение 2, не ключ B; поиск прекращается.
<?php
$stocks = ['A' => 0, 'B' => 2, 'C' => 4];
$stock = array_find($stocks, fn($value, $key) => $value > 0);
var_dump($stock);
Ожидаемый результат
int(2)
Обход идёт по порядку массива и заканчивается, как только общий ответ уже известен.
<?php
// PHP 8.4+.
$products = [['sku' => 'A', 'stock' => 0], ['sku' => 'B', 'stock' => 3]];
$product = array_find($products, function ($row, $key) {
return $row['stock'] > 0;
});
if ($product !== null) {
echo 'Первый доступный товар: ', $product['sku'], "\n";
echo 'Можно предложить: ', $product['stock'], ' шт.', "\n";
}
$nullValue = array_find(['A' => null], function ($value, $key) { return $key === 'A'; });
$absentValue = array_find([], function ($value, $key) { return true; });
echo 'Тип найденного null: ', get_debug_type($nullValue), "\n";
echo 'Тип результата отсутствующего совпадения: ', get_debug_type($absentValue), "\n";
Ожидаемый результат
Первый доступный товар: B
Можно предложить: 3 шт.
Тип найденного null: null
Тип результата отсутствующего совпадения: null
Return callback — только bool проверки. Return array_find — вся выбранная строка B; она используется для чтения sku и stock. Если значением может быть null, один результат null не различает успех и отсутствие. Тогда используйте find_key и прочитайте значение отдельно по найденному ключу.
Нюансы и выбор. Последние два результата одинаковы: найденный null неотличим от отсутствия результата по одному возвращённому значению. Если null допустим в данных, найдите ключ через array_find_key. Форма строк products здесь заранее задана. Для PHP 8.2/8.3 тот же договор выражается foreach с ранним return из функции; не стройте array_filter всех элементов, если нужен только первый ответ. Число вызовов callback зависит от места решающего элемента. Не меняйте проверяемый массив из callback и не прячьте в проверке отправку запросов.
Сравните: array_all, array_any, array_find_key, array_filter. Выбрать операцию по задаче.
array_find_keyНайти ключ первого элемента по правилу, чтобы затем обратиться именно к нему.
PHP 8.4+ · standard
array_find_key(array $array, callable $callback): mixedНайти ключ первого элемента по правилу, чтобы затем обратиться именно к нему.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив, который проверяется в его текущем порядке. |
| callback | Проверка callback(mixed $value, mixed $key): bool. Возвращайте осмысленный bool; передаются значение и ключ. |
| Возврат | Первое подходящее имя ключа; null, если совпадения нет. |
| Отказ и диагностика | Неверный тип массива или невызываемый callback даёт TypeError. Исключение callback передаётся вызывающему коду; оно не является результатом false/null. |
Callback — функция, переданная другой функции. Здесь PHP вызывает её для очередного элемента: первый параметр получает значение, второй — ключ. function ($stock, $sku) { return $stock > 0; } объявляет такую проверку; return отдаёт bool. Короткая fn(...) => выражение автоматически возвращает результат одного выражения.
Для этого примера: передача функции как значения.
- stocks: A=0, B=2, C=4.
- Callback принимает первое положительное значение у B.
- Возвращается ключ B; само значение массива не заменяется.
<?php
$stocks = ['A' => 0, 'B' => 2, 'C' => 4];
$sku = array_find_key($stocks, fn($value, $key) => $value > 0);
echo $sku, "\n";
Ожидаемый результат
B
Обход идёт по порядку массива и заканчивается, как только общий ответ уже известен.
<?php
// PHP 8.4+.
$values = [0 => null, 1 => 'ready'];
$key = array_find_key($values, function ($value, $key) {
return $value === null;
});
if ($key !== null) {
$values[$key] = 'waiting';
echo 'Незаполненная позиция ', $key, ' получила статус ', $values[$key], "\n";
}
$missing = array_find_key([], function ($value, $key) { return true; });
if ($missing === null) {
echo "В пустом списке нечего изменять\n";
}
Ожидаемый результат
Незаполненная позиция 0 получила статус waiting
В пустом списке нечего изменять
Find_key возвращает ключ 0, и !== null правильно распознаёт его. По этому ключу программа записывает согласованный статус waiting. Пустой вход возвращает null. Ключ массива не хранится как null: при создании такой ключ преобразуется, поэтому null пригоден здесь как признак отсутствия.
Нюансы и выбор. Проверка !== null сохраняет успешный ключ 0. У PHP-массива null не хранится как отдельный тип ключа: он преобразуется; поэтому null здесь пригоден как маркер отсутствия. Документированный тип результата mixed; фактический найденный ключ — int или string. Для PHP 8.2/8.3 тот же договор выражается foreach с ранним return из функции; не стройте array_filter всех элементов, если нужен только первый ответ. Число вызовов callback зависит от места решающего элемента. Не меняйте проверяемый массив из callback и не прячьте в проверке отправку запросов.
Сравните: array_all, array_any, array_find, array_filter. Выбрать операцию по задаче.
array_key_firstПрочитать первый ключ в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
PHP 7.3+ · standard
array_key_first(array $array): int|string|nullПрочитать первый ключ в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив. «Первый/последний» относится к порядку элементов, не к минимальному/максимальному ключу или значению. |
| Возврат | Найденный ключ; null для пустого массива. |
| Отказ и диагностика | Для аргумента другого типа PHP 8 выдаёт TypeError. Пустой массив допустим и не создаёт предупреждения. |
- Массив хранит B=2, затем A=0.
- Вернуть B из текущей границы.
- Использовать возврат для подписи остатка; массив не меняется.
<?php
$stocks = ['B' => 2, 'A' => 0];
$sku = array_key_first($stocks);
if ($sku !== null) {
echo "Товар ", $sku, ": ", $stocks[$sku], " шт.\n";
}
Ожидаемый результат
Товар B: 2 шт.
В sku возвращается ключ B, а не остаток. После проверки !== null он используется в stocks[sku], чтобы прочитать соответствующее количество. Строгая проверка допускает полезный ключ 0 или пустую строку. Названия B/A специально записаны без сортировки: берётся граница текущего порядка.
<?php
$stocks = ['B' => 2, 'A' => 0];
next($stocks);
array_key_first($stocks);
echo key($stocks), "\n";
var_dump(array_key_first([]));
Ожидаемый результат
A
NULL
next передвинул указатель на A, чтение границы оставило его там. key читает позицию указателя; функция границы её не использует.
Нюансы и выбор. Ключ 0 или пустая строка — успешный результат; проверяйте !== null, а не if($key). Не создавайте весь array_keys ради единственного граничного ключа. reset/end тоже дают граничное значение, но меняют указатель; array_shift/array_pop ещё и удаляют элемент.
Сравните: array_key_last, array_first, array_last, reset, end. Выбрать операцию по задаче.
array_key_lastПрочитать последний ключ в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
PHP 7.3+ · standard
array_key_last(array $array): int|string|nullПрочитать последний ключ в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив. «Первый/последний» относится к порядку элементов, не к минимальному/максимальному ключу или значению. |
| Возврат | Найденный ключ; null для пустого массива. |
| Отказ и диагностика | Для аргумента другого типа PHP 8 выдаёт TypeError. Пустой массив допустим и не создаёт предупреждения. |
- Массив хранит B=2, затем A=0.
- Вернуть A из текущей границы.
- Использовать возврат для подписи остатка; массив не меняется.
<?php
$stocks = ['B' => 2, 'A' => 0];
$sku = array_key_last($stocks);
if ($sku !== null) {
echo "Товар ", $sku, ": ", $stocks[$sku], " шт.\n";
}
Ожидаемый результат
Товар A: 0 шт.
В sku возвращается ключ A, а не остаток. После проверки !== null он используется в stocks[sku], чтобы прочитать соответствующее количество. Строгая проверка допускает полезный ключ 0 или пустую строку. Названия B/A специально записаны без сортировки: берётся граница текущего порядка.
<?php
$stocks = ['B' => 2, 'A' => 0];
next($stocks);
array_key_last($stocks);
echo key($stocks), "\n";
var_dump(array_key_last([]));
Ожидаемый результат
A
NULL
next передвинул указатель на A, чтение границы оставило его там. key читает позицию указателя; функция границы её не использует.
Нюансы и выбор. Ключ 0 или пустая строка — успешный результат; проверяйте !== null, а не if($key). Не создавайте весь array_keys ради единственного граничного ключа. reset/end тоже дают граничное значение, но меняют указатель; array_shift/array_pop ещё и удаляют элемент.
Сравните: array_key_first, array_first, array_last, reset, end. Выбрать операцию по задаче.
array_firstПрочитать первое значение в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
PHP 8.5+ · standard
array_first(array $array): mixedПрочитать первое значение в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив. «Первый/последний» относится к порядку элементов, не к минимальному/максимальному ключу или значению. |
| Возврат | Найденное значение; null для пустого массива. |
| Отказ и диагностика | Для аргумента другого типа PHP 8 выдаёт TypeError. Пустой массив допустим и не создаёт предупреждения. |
- Массив хранит B=2, затем A=0.
- Вернуть 2 из текущей границы.
- Использовать возврат для подписи остатка; массив не меняется.
<?php
$stocks = ['B' => 2, 'A' => 0];
$quantity = array_first($stocks);
echo "На границе списка: ", $quantity, " шт.\n";
if ($quantity === 0) { echo "Нужно пополнение\n"; }
Ожидаемый результат
На границе списка: 2 шт.
Значение 2 возвращается прямо в quantity. Здесь массив заведомо непустой и содержит только целые остатки. Число 0 — полезный остаток, по нему программа сообщает о пополнении; проверка if(quantity) смешала бы его с неудачей. В PHP 8.2–8.4 сначала получите соответствующий ключ, проверьте его на null и прочитайте значение по ключу.
<?php
$stocks = ['B' => 2, 'A' => 0];
next($stocks);
array_first($stocks);
echo key($stocks), "\n";
var_dump(array_first([]));
Ожидаемый результат
A
NULL
next передвинул указатель на A, чтение границы оставило его там. key читает позицию указателя; функция границы её не использует.
Нюансы и выбор. Null может быть настоящим значением непустого массива. Если важно отличить его от пустоты, проверьте $array !== [] либо сначала получите соответствующий ключ. В PHP 8.2–8.4 значение можно прочитать по array_key_first, проверив ключ на null. reset/end тоже дают граничное значение, но меняют указатель; array_shift/array_pop ещё и удаляют элемент.
Сравните: array_key_first, array_key_last, array_last, reset, end. Выбрать операцию по задаче.
array_lastПрочитать последнее значение в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
PHP 8.5+ · standard
array_last(array $array): mixedПрочитать последнее значение в порядке массива, не удаляя элемент и не переставляя внутренний указатель.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив. «Первый/последний» относится к порядку элементов, не к минимальному/максимальному ключу или значению. |
| Возврат | Найденное значение; null для пустого массива. |
| Отказ и диагностика | Для аргумента другого типа PHP 8 выдаёт TypeError. Пустой массив допустим и не создаёт предупреждения. |
- Массив хранит B=2, затем A=0.
- Вернуть 0 из текущей границы.
- Использовать возврат для подписи остатка; массив не меняется.
<?php
$stocks = ['B' => 2, 'A' => 0];
$quantity = array_last($stocks);
echo "На границе списка: ", $quantity, " шт.\n";
if ($quantity === 0) { echo "Нужно пополнение\n"; }
Ожидаемый результат
На границе списка: 0 шт.
Нужно пополнение
Значение 0 возвращается прямо в quantity. Здесь массив заведомо непустой и содержит только целые остатки. Число 0 — полезный остаток, по нему программа сообщает о пополнении; проверка if(quantity) смешала бы его с неудачей. В PHP 8.2–8.4 сначала получите соответствующий ключ, проверьте его на null и прочитайте значение по ключу.
<?php
$stocks = ['B' => 2, 'A' => 0];
next($stocks);
array_last($stocks);
echo key($stocks), "\n";
var_dump(array_last([]));
Ожидаемый результат
A
NULL
next передвинул указатель на A, чтение границы оставило его там. key читает позицию указателя; функция границы её не использует.
Нюансы и выбор. Null может быть настоящим значением непустого массива. Если важно отличить его от пустоты, проверьте $array !== [] либо сначала получите соответствующий ключ. В PHP 8.2–8.4 значение можно прочитать по array_key_last, проверив ключ на null. reset/end тоже дают граничное значение, но меняют указатель; array_shift/array_pop ещё и удаляют элемент.
Сравните: array_key_first, array_key_last, array_first, reset, end. Выбрать операцию по задаче.
key_existsУзнать псевдоним array_key_exists в старом коде: договор проверки ключа полностью тот же.
PHP 4.0.6+ · standard
key_exists(string|int|float|bool|resource|null $key, array $array): boolУзнать псевдоним array_key_exists в старом коде: договор проверки ключа полностью тот же.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| key | Искомый ключ. Для ясного договора используйте int или string; прочие допустимые типы преобразуются по правилам ключей. null как аргумент deprecated с PHP 8.5 — используйте пустую строку. |
| array | Массив, проверяется только первый уровень. Объекты не поддерживаются с PHP 8.0; для свойства существует property_exists. |
| Возврат | true, если ключ присутствует, включая значение null; false при отсутствии. |
| Отказ и диагностика | Неподдерживаемый тип ключа или аргумент не-массив вызывает TypeError. Преобразования некоторых ключей могут давать диагностику; не используйте ресурс как бизнес-ключ. |
- В сохранённой записи есть текст комментария.
- Наличие ключа с null разрешает очистку.
- Пустой массив правки не меняет запись.
<?php
$saved = ['comment' => 'Позвонить заранее'];
$patch = ['comment' => null];
if (key_exists('comment', $patch)) {
$saved['comment'] = $patch['comment'];
}
echo 'Комментарий: ', $saved['comment'] ?? 'не указан', "\n";
$patch = [];
if (key_exists('comment', $patch)) {
$saved['comment'] = $patch['comment'];
}
echo 'После пустой правки: ', $saved['comment'] ?? 'не указан', "\n";
Ожидаемый результат
Комментарий: не указан
После пустой правки: не указан
По договору этой локальной правки null означает очистку. Проверка находит существующий ключ comment и возвращает true даже при null; присваивание действительно очищает значение. Во второй правке ключа нет: false пропускает присваивание. ?? выбирает текст для отсутствующего/null комментария. Isset дал бы false уже в первом случае и помешал бы очистить поле. Тип и разрешённые имена входных полей проверяют отдельно.
<?php
$payload = ['product' => ['stock' => 0]];
var_dump(key_exists('stock', $payload));
var_dump(key_exists('stock', $payload['product']));
echo $payload['product']['stock'], "\n";
Ожидаемый результат
bool(false)
bool(true)
0
Функция не ищет рекурсивно. Форма product здесь известна; для внешнего JSON сначала убедитесь, что product — массив.
Нюансы и выбор. Не заменяйте проверку наличия на empty: empty считает пустыми и 0, и "0", и false. Наличие поля не доказывает его тип и допустимость. В PHP 8.0 набор допустимых скалярных типов ключа расширен, но наиболее понятный контракт приложения — именованный строковый ключ или целочисленный индекс. В новом коде полное имя array_key_exists обычно читается яснее; иной производительности этот псевдоним не обещает.
Сравните: array_key_exists, in_array, array_keys. Выбрать операцию по задаче.
array_count_valuesСосчитать частоту строковых кодов или целых значений, например заказы по статусам.
PHP 4+ · standard
array_count_values(array $array): arrayСосчитать частоту строковых кодов или целых значений, например заказы по статусам.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив значений; считаются только int и string. Исходные ключи не важны. |
| Возврат | Словарь значение → число его появлений. Новые ключи подчиняются правилам ключей PHP. |
| Отказ и диагностика | Каждое значение другого типа вызывает E_WARNING и пропускается. Это не рекурсивный счётчик вложенных записей. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Вход new,paid,new.
- Собрать частоты new=2 и paid=1.
- Показать отчёт и число ожидающих оплаты.
<?php
$statuses = ['new', 'paid', 'new'];
$counts = array_count_values($statuses);
foreach ($counts as $status => $quantity) {
echo 'Статус ', $status, ': ', $quantity, "\n";
}
$waiting = $counts['new'] ?? 0;
echo 'Ожидают оплаты: ', $waiting, "\n";
Ожидаемый результат
Статус new: 2
Статус paid: 1
Ожидают оплаты: 2
New встретился дважды и стал ключом со значением 2; paid — ключом со значением 1. Возвращённый словарь пригоден и для полного отчёта, и для обращения к одному статусу. Если new вообще не встретился, ключа не будет и ?? вернёт 0. Если необходимо заранее показывать все статусы, начните с array_fill_keys и прибавляйте количества обычным foreach.
<?php
echo json_encode(array_count_values([1, '1', '01'])), "\n";
$rows = [['status' => 'paid'], ['status' => 'new'], ['status' => 'paid']];
echo json_encode(array_count_values(array_column($rows, 'status'))), "\n";
Ожидаемый результат
{"1":2,"01":1}
{"paid":2,"new":1}
1 и строка "1" превращаются в один ключ; "01" остаётся отдельным. Во втором опыте сначала явно извлекается поле уже проверенных строк.
Нюансы и выбор. Для точного разделения разных типов задайте собственный ключ с меткой типа или используйте иной формат агрегации. Не приводите все входы к строке без договора: null и пустая строка могут начать означать одно и то же. Для сумм по категориям потребуется array_reduce или обычный foreach, а не подсчёт повторов.
Сравните: count, array_column, array_reduce, array_unique. Выбрать операцию по задаче.
array_flipПоменять направление уникального соответствия: из ID→код получить код→ID.
PHP 4+ · standard
array_flip(array $array): arrayПоменять направление уникального соответствия: из ID→код получить код→ID.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив, значения которого должны быть int/string, чтобы стать ключами. |
| Возврат | Новый массив: старые значения становятся ключами, старые ключи — значениями. Позднее повторяющееся значение побеждает. |
| Отказ и диагностика | Для каждого значения неподходящего типа выдаётся предупреждение, а пара пропускается. Другой тип array даёт TypeError. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Codes связывает 41→A и 72→B.
- Flip разворачивает B→72.
- Полученный 72 читает остаток 5 в другом словаре.
<?php
$codes = [41 => 'A', 72 => 'B'];
$stockById = [41 => 0, 72 => 5];
$idByCode = array_flip($codes);
$requestedCode = 'B';
$id = $idByCode[$requestedCode];
echo 'Код ', $requestedCode, ' → ID ', $id, "\n";
echo 'Доступно: ', $stockById[$id], ' шт.', "\n";
Ожидаемый результат
Код B → ID 72
Доступно: 5 шт.
Flip возвращает новое соответствие A→41, B→72. Код B заранее известен и уникален; обращение idByCode[B] возвращает 72. Это число затем служит ключом в отдельном словаре остатков. Так показано, зачем нужен обратный индекс. Внешний неизвестный код сначала проверяют через array_key_exists, а повторы кодов запрещают либо хранят список ID; следующий опыт показывает потерю при повторе.
<?php
$codes = [41 => 'A', 72 => 'A'];
echo json_encode(array_flip($codes)), "\n";
echo json_encode(array_flip(array_flip($codes))), "\n";
Ожидаемый результат
{"A":72}
{"72":"A"}
Двойной flip не восстановил запись 41: информация уже потеряна. Для одного кода с несколькими ID нужно явно собирать список ID под ключом.
Нюансы и выбор. Это не универсальное преобразование множества и не операция без потерь. Числовые строки могут стать целочисленными ключами; объекты, массивы, bool и null не являются допустимыми значениями для такого разворота. Для проверки принадлежности набору часто яснее array_fill_keys с фиксированным true.
Сравните: array_fill_keys, array_search, array_combine, array_unique. Выбрать операцию по задаче.
sizeofПрочитать псевдоним count: sizeof считает элементы, а не размер массива в байтах.
PHP 4+ · standard
sizeof(Countable|array $value, int $mode = COUNT_NORMAL): intПрочитать псевдоним count: sizeof считает элементы, а не размер массива в байтах.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| value | Массив либо объект, реализующий Countable::count(). Не любая переменная или объект является countable. |
| mode | COUNT_NORMAL (0) считает верхний уровень. COUNT_RECURSIVE (1) дополнительно считает элементы вложенных массивов; вложенные контейнеры тоже учитываются. |
| Возврат | Целое количество элементов. Для Countable вызывается его собственный метод count; это не обязательно число публичных свойств. |
| Отказ и диагностика | В PHP 8 неподходящий тип даёт TypeError. В PHP 7.2 появилась диагностика для неподходящих типов; ранее не-null скаляр давал 1, null — 0. Рекурсивная ссылка при COUNT_RECURSIVE вызывает E_WARNING и не является корректным счётом листьев. |
- Есть две строки: A с 3 упаковками и B с 1.
- Посчитать строки отдельно от суммы количеств.
- Показать 2 позиции и 4 упаковки.
<?php
$cart = ['A' => 3, 'B' => 1];
$lineCount = sizeof($cart);
$packageCount = array_sum($cart);
echo 'Разных позиций: ', $lineCount, "\n";
echo 'Упаковок к сборке: ', $packageCount, "\n";
if ($lineCount === 0) { echo "Корзина пуста\n"; }
Ожидаемый результат
Разных позиций: 2
Упаковок к сборке: 4
sizeof возвращает 2, потому что на верхнем уровне две пары: A→3 и B→1. Этот результат отвечает за число разных строк; array_sum отдельно возвращает 4 упаковки. Наличие вложенных полей у строки не увеличило бы обычный count. Рекурсивный режим ниже считает также элементы контейнеров и не заменяет сумму количеств.
<?php
$groups = [['A', 'B'], ['C']];
echo sizeof($groups), "\n";
echo sizeof($groups, COUNT_RECURSIVE), "\n";
try {
sizeof(null);
} catch (TypeError) {
echo "Ожидался массив или Countable\n";
}
Ожидаемый результат
2
5
Ожидался массив или Countable
Рекурсивно получилось 2 контейнера + 3 значения. Это не число товаров-листьев. На границе API null сначала обрабатывают по договору, а не автоматически превращают в пустой список.
Нюансы и выбор. Обычный размер массива хранится в его структуре; не объявляйте count линейным обходом каждого элемента. Рекурсивный режим действительно обходит вложенные массивы, а пользовательский Countable может выполнять произвольную работу. Последний числовой ключ не равен количеству. Ссылки на собственный массив не превращают COUNT_RECURSIVE в безопасный универсальный обход графа. Название count обычно яснее: sizeof не измеряет память.
Сравните: count, array_sum, array_key_last. Выбрать операцию по задаче.
array_change_key_caseНормализовать регистр строковых ключей, не меняя значения.
PHP 4.2+ · standard
array_change_key_case(array $array, int $case = CASE_LOWER): arrayНормализовать регистр строковых ключей, не меняя значения.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Исходный массив; числовые ключи остаются прежними. |
| case | CASE_LOWER — нижний регистр, CASE_UPPER — верхний. С PHP 8.2 преобразуются только ASCII-буквы. |
| Возврат | Новый массив; при столкновении преобразованных ключей побеждает более позднее значение. |
| Отказ и диагностика | Неверный тип аргумента — TypeError. Допустимы документированные CASE_* режимы; функция не диагностирует потерю значения при столкновении. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Входные ключи Host, PORT, 7.
- Изменить строковые ключи на host/port, сохранить 7.
- Прочитать новый адрес; исходный Host по-прежнему доступен.
<?php
$received = ['Host' => 'mail.local', 'PORT' => 587, 7 => 'служебная отметка'];
$settings = array_change_key_case($received, CASE_LOWER);
echo 'Сервер: ', $settings['host'], ':', $settings['port'], "\n";
echo 'Числовой ключ 7: ', $settings[7], "\n";
echo 'Исходное имя Host: ', $received['Host'], "\n";
Ожидаемый результат
Сервер: mail.local:587
Числовой ключ 7: служебная отметка
Исходное имя Host: mail.local
Case_lower — константа нижнего регистра. Возвращённый массив получает строковые ключи host/port; числовой 7 сохраняется. Значения не меняются. Echo строит адрес из унифицированных имён, а последняя строка показывает, что исходный массив received остался прежним. Здесь поставщик разрешает только ASCII-имена настроек; ниже разобрана коллизия имён, которую необходимо обнаружить до потери значения.
<?php
$incoming = ['Token' => 'first', 'TOKEN' => 'second'];
$normalized = array_change_key_case($incoming, CASE_LOWER);
if (count($incoming) !== count($normalized)) {
echo "Конфликт имён: требуется решение
";
}
echo json_encode(array_change_key_case(['mode' => 'test'], CASE_UPPER)), "
";
Ожидаемый результат
Конфликт имён: требуется решение
{"MODE":"test"}
В конфигурации нельзя молча считать Token и TOKEN двумя разными полями после нормализации. Здесь конфликт обнаружен до применения настроек.
Нюансы и выбор. Это не Unicode-преобразование русских ключей и не переименование вложенных полей. Предварительно решите, допустимы ли дубликаты без учёта регистра.
Сравните: array_keys, array_combine, array_replace. Выбрать операцию по задаче.
array_walkВыполнить действие над каждым элементом или изменить его значение на месте.
PHP 4+ · standard
array_walk(array|object &$array, callable $callback, mixed $arg = null): trueЗадача и маршрут результата. Нужно изменить каждую цену в существующем прайсе. Callback получает связь с элементом через &$price; += пишет в массив. Возврат самой array_walk — статус true, полезные цены остаются в prices.
Выполнить действие над каждым элементом или изменить его значение на месте.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив либо объект; функция обходит элементы независимо от текущего внутреннего указателя. |
| callback | callback(value, key); для изменения значения объявите первый параметр как &$value. Возврат callback не заменяет элемент. |
| arg | Если передан, становится третьим аргументом callback. |
| Возврат | Всегда true; изменённые значения находятся в исходной переменной. С PHP 8.2 тип возврата уточнён с bool до true. |
| Отказ и диагностика | С PHP 7.1 нехватка аргументов callback — ArgumentCountError. С PHP 8 ссылка на второй/третий параметр callback вызывает E_WARNING. Менять ключи, добавлять, удалять или переставлять элементы при обходе нельзя: поведение не определено. |
Знак & перед первым параметром в справочной сигнатуре означает изменение переданного массива. В самом вызове & не пишут: передают переменную, а не временное выражение. Запись function ($value) { return ...; } создаёт функцию, которую операция вызывает для каждого элемента; return передаёт ей результат. В объявлении function (&$value, $key) ссылка относится к значению элемента; ключ остаётся данными для чтения.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения; что означает ссылка &.
- Метки red и blue
- Вызвать действие с value и key
- Напечатать пары, не строя новый массив
<?php
$labels = ['a' => 'red', 'b' => 'blue'];
$ok = array_walk($labels, function ($value, $key) {
echo $key, '=', $value, "
";
});
var_dump($ok);
Ожидаемый результат
a=red
b=blue
bool(true)
Результат walk — признак завершения, а не собранный текст и не массив.
<?php
$prices = ['p1' => 100, 'p2' => 250];
$status = array_walk($prices, function (&$price, $key, $fee) {
$price += $fee;
}, 20);
if ($status) {
echo "Упаковка включена в каждую цену\n";
}
foreach ($prices as $id => $price) {
echo $id, ': ', $price, ' коп.', "\n";
}
Ожидаемый результат
Упаковка включена в каждую цену
p1: 120 коп.
p2: 270 коп.
Третий аргумент 20 передаётся callback как fee для каждого элемента. Первый параметр &$price связан с его значением, поэтому += изменяет prices. Return у callback не нужен и не заменяет элемент. Status получает true, а дальнейший foreach читает изменённые цены из prices, не из status. Состав и порядок массива внутри walk не меняют.
Нюансы и выбор. Нельзя напрямую передать strtolower: walk передаёт также ключ, а многие встроенные функции отвергают лишние аргументы. Оберните нужный вызов в собственную функцию с подходящими параметрами. Возвращённый false не прекращает обход.
Сравните: array_map, array_walk_recursive, array_filter. Выбрать операцию по задаче.
array_walk_recursiveПройти листья вложенных массивов, например обработать текстовые поля разобранного JSON.
PHP 5+ · standard
array_walk_recursive(array|object &$array, callable $callback, mixed $arg = null): trueПройти листья вложенных массивов, например обработать текстовые поля разобранного JSON.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Вложенный массив либо объект верхнего уровня, рассматриваемый как массив. Внутрь вложенных объектов функция не спускается. |
| callback | callback(value, key): листья, не контейнеры-массивы. &$value позволяет менять лист. Ключ — локальный, не полный путь. |
| arg | Необязательный третий аргумент callback. |
| Возврат | true (точный тип с PHP 8.2); новый массив не возвращается. |
| Отказ и диагностика | Ошибки callback распространяются наружу. Не меняйте структуру дерева при обходе; используйте конечное дерево без циклических ссылок. Неподходящие типы параметров callback могут приводить к TypeError. |
Знак & перед первым параметром в справочной сигнатуре означает изменение переданного массива. В самом вызове & не пишут: передают переменную, а не временное выражение. Запись function ($value) { return ...; } создаёт функцию, которую операция вызывает для каждого элемента; return передаёт ей результат. Лист — значение, которое уже не является массивом. use (&$sum) ниже даёт функции доступ к внешнему накопителю по ссылке.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения; рекурсивный обход и путь.
- Ветви left и right содержат qty
- Войти в каждый вложенный массив
- Получить листья qty=2 и qty=3
<?php
$tree = ['left' => ['qty' => 2], 'right' => ['qty' => 3]];
array_walk_recursive($tree, function ($value, $key) {
echo $key, '=', $value, "
";
});
Ожидаемый результат
qty=2
qty=3
Ключи left/right в callback не пришли: они обозначают контейнеры. Если нужен путь left.qty, нужна собственная рекурсивная функция.
Сначала выше показан каждый локальный ключ листа. Теперь меняем только строковые значения. &$value связывает параметр с листом; is_string проверяет тип, trim возвращает очищенную строку. Ни callback, ни его return не возвращают новое дерево.
<?php
$payload = ['customer' => ['name' => ' Анна '], 'items' => [['code' => ' p1 ', 'qty' => 2]]];
$status = array_walk_recursive($payload, function (&$value, $key) {
if (is_string($value)) {
$value = trim($value);
}
});
echo 'Получатель: [', $payload['customer']['name'], "]\n";
echo 'Артикул: [', $payload['items'][0]['code'], "]\n";
echo 'Количество: ', $payload['items'][0]['qty'], "\n";
if ($status) { echo "Обход завершён\n"; }
Ожидаемый результат
Получатель: [Анна]
Артикул: [p1]
Количество: 2
Обход завершён
Callback получает только листья: строку имени, строку артикула и число 2. Is_string допускает первые два; trim возвращает строку без крайних пробелов. Присваивание через &$value меняет соответствующий лист самого payload. Число пропускается и остаётся 2. Status содержит true — статус обхода; содержательные результаты читаются из payload. Квадратные скобки в выводе специально показывают отсутствие крайних пробелов. Ключ callback локальный и не сообщает путь родителя.
<?php
$sum = 0;
$rows = [['qty' => 2], ['qty' => 3]];
array_walk_recursive($rows, function ($value, $key) use (&$sum) {
if ($key === 'qty') { $sum += $value; }
});
echo $sum, "
";
Ожидаемый результат
5
Возврат callback не выходит из внешней функции и не останавливает весь walk. Когда нужно первое совпадение и ранний выход, явно пишите рекурсивный поиск.
Нюансы и выбор. Повторяющийся ключ name в разных ветках не идентифицирует одно поле. Нельзя восстановить родительский путь из одного callback(value,key); передавайте путь в своей рекурсии. Глубина и размер недоверенного JSON ограничиваются ещё при приёме.
Сравните: array_walk, array_map, array_reduce. Выбрать операцию по задаче.
array_merge_recursiveСобрать несколько значений одноимённых полей в общее дерево.
PHP 4.0.1+ · standard
array_merge_recursive(array ...$arrays): arrayСобрать несколько значений одноимённых полей в общее дерево.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| arrays | Ноль или больше массивов; обрабатываются слева направо. Без аргументов [] с PHP 7.4. |
| Правило совпадения | Совпавшие строковые ключи объединяются рекурсивно: два скаляра превращаются в массив. Числовые значения добавляются с перенумерацией, даже при совпавшем ключе. |
| Возврат | Новый массив; исходные массивы не изменяются. Это не глубокое клонирование объектов внутри значений. |
| Отказ и диагностика | Немассивный аргумент — TypeError. Рекурсивные варианты применяйте к конечным деревьям; циклические ссылки не являются поддержкой произвольного графа. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Tag равен red в одном источнике и blue в другом.
- Создать общий вложенный список двух меток.
- Перебрать каждую метку из combined[tag].
<?php
$firstSource = ['tag' => 'red'];
$secondSource = ['tag' => 'blue'];
$combined = array_merge_recursive($firstSource, $secondSource);
foreach ($combined['tag'] as $tag) {
echo 'Предложенная метка: ', $tag, "\n";
}
echo 'Первый источник всё ещё: ', $firstSource['tag'], "\n";
Ожидаемый результат
Предложенная метка: red
Предложенная метка: blue
Первый источник всё ещё: red
На одинаковом строковом ключе tag встретились две строки. Recursive merge возвращает под этим ключом вложенный массив [red,blue], поэтому следующий foreach проходит именно combined[tag]. Это полезно, когда по договору нужно собрать все варианты поля. Тип tag изменился со строки на массив; для одиночного порта/флага такой результат обычно непригоден. Следующий опыт сохраняет сравнение merge_recursive с replace_recursive.
<?php
$base = ['mail' => ['host' => 'local', 'port' => 25]];
$patch = ['mail' => ['port' => 587]];
echo json_encode(array_merge_recursive($base, $patch)), "\n";
echo json_encode(array_replace_recursive($base, $patch)), "\n";
Ожидаемый результат
{"mail":{"host":"local","port":[25,587]}}
{"mail":{"host":"local","port":587}}
Два номера порта не являются корректным значением одного порта. Выбор операции определяется схемой данных.
Нюансы и выбор. Функция не удаляет дубликаты. Для объединения уникальных меток нужен отдельный шаг на известном уровне; для правки настроек обычно replace_recursive.
Сравните: array_merge, array_replace, array_replace_recursive. Выбрать операцию по задаче.
array_replace_recursiveПрименить частичный патч к вложенному словарю.
PHP 5.3+ · standard
array_replace_recursive(array $array, array ...$replacements): arrayПрименить частичный патч к вложенному словарю.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Обязательный первый массив. |
| replacements | Ноль или больше массивов-патчей, слева направо. |
| Правило совпадения | Если старое и новое значения оба массивы, рекурсивно обновляет их ключи. Во всех остальных случаях правое значение заменяет левое, даже при смене скаляра на массив или обратно. |
| Возврат | Новый массив; исходные массивы не изменяются. Это не глубокое клонирование объектов внутри значений. |
| Отказ и диагностика | Немассивный аргумент — TypeError. Рекурсивные варианты применяйте к конечным деревьям; циклические ссылки не являются поддержкой произвольного графа. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- В base есть mail.host и mail.port=25.
- Войти в mail и заменить только port на 587.
- Прочитать сохранённый host и новый port в строке адреса.
<?php
$base = ['mail' => ['host' => 'mail.local', 'port' => 25]];
$patch = ['mail' => ['port' => 587]];
$settings = array_replace_recursive($base, $patch);
echo 'Адрес для подключения: ', $settings['mail']['host'], ':', $settings['mail']['port'], "\n";
echo 'Исходный порт: ', $base['mail']['port'], "\n";
Ожидаемый результат
Адрес для подключения: mail.local:587
Исходный порт: 25
На ключе mail оба значения — массивы, поэтому функция входит внутрь. Там совпадает port: 25 заменяется на 587. Host в правке отсутствует, значит сохраняется. Возврат settings — целая новая структура; её два поля соединены в адрес, сетевого подключения этот пример не делает. При числовых ключах действует такое же замещение по ключу, поэтому список ролей требует отдельной политики: следующий опыт показывает этот крайний случай.
<?php
$base = ['roles' => ['reader','editor'], 'cache' => ['ttl' => 60]];
$patch = ['roles' => ['admin'], 'cache' => false];
echo json_encode(array_replace_recursive($base, $patch)), "\n";
Ожидаемый результат
{"roles":["admin","editor"],"cache":false}
roles[1] сохранился: список тоже массив с ключами. Если новый список должен полностью заменить старый, делайте явное присваивание roles после проверки.
Нюансы и выбор. Это не стандарт JSON Merge Patch: null не означает удаление, а числовые ключи списков обновляются по индексам. Для удаления и атомарных списков нужен явно описанный договор.
Сравните: array_merge, array_merge_recursive, array_replace. Выбрать операцию по задаче.
array_spliceЗаменить участок списка и отдельно получить удалённые элементы.
PHP 4+ · standard
array_splice(array &$array, int $offset, ?int $length = null, mixed $replacement = []): arrayЗадача и маршрут результата. Нужно заменить шаг процесса и отдельно сообщить, какой шаг удалён. Функция изменяет steps, а возвращает только удалённое; два результата должны быть прочитаны из разных мест.
Заменить участок списка и отдельно получить удалённые элементы.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемый исходный массив. Целочисленные ключи перенумеровываются. |
| offset | Позиция с нуля; отрицательная — от конца. |
| length | null/отсутствие: до конца; положительная: максимум удаляемых; отрицательная: оставить столько с конца; 0: только вставить. null поддержан с PHP 8. |
| replacement | Значения вставки; их ключи не сохраняются. Немассив преобразуется к массиву: чтобы вставить null/объект/массив одним элементом, оберните в [значение]. |
| Возврат | Массив удалённых значений; изменённый список остаётся в первом аргументе. |
| Отказ и диагностика | Первый аргумент должен быть передаваемой переменной подходящего типа. Смещение за пределами списка не даёт ошибки; может получиться вставка у края. |
Знак & перед первым параметром в справочной сигнатуре означает изменение переданного массива. В самом вызове & не пишут: передают переменную, а не временное выражение.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Список draft, review, done
- Убрать review и вставить approve
- Возврат [review], исходник draft, approve, done
<?php
$steps = ['draft', 'review', 'done'];
$removed = array_splice($steps, 1, 1, ['approve']);
foreach ($removed as $step) {
echo 'Удалённый шаг: ', $step, "\n";
}
echo "Текущий маршрут\n";
foreach ($steps as $position => $step) {
echo $position + 1, '. ', $step, "\n";
}
Ожидаемый результат
Удалённый шаг: review
Текущий маршрут
1. draft
2. approve
3. done
Первый аргумент steps меняется на месте. Со второй позиции удаляется один review, вместо него вставляется approve. Return содержит [review] и присваивается removed. Если присвоить результат обратно steps, дальнейший маршрут будет потерян. Позиция splice не равна id; для удаления ключа словаря подходит unset.
<?php
$cells = ['id','name'];
array_splice($cells, 1, 0, [null]);
echo json_encode($cells), "
";
array_splice($cells, -1, null, [['label' => 'title']]);
echo json_encode($cells), "
";
Ожидаемый результат
["id",null,"name"]
["id",null,{"label":"title"}]
[null] — один пустой элемент; null как replacement сам по себе преобразовался бы в пустой массив. Дополнительные скобки также удерживают вложенную запись одним элементом.
Нюансы и выбор. Не используйте splice как удаление по ID: offset означает позицию. Для словаря точнее unset($array[$id]); для неизменяющего среза — slice.
Сравните: array_slice, array_push, array_shift. Выбрать операцию по задаче.
array_reverseПолучить обратный порядок элементов, не сортируя их значения.
PHP 4+ · standard
array_reverse(array $array, bool $preserve_keys = false): arrayПолучить обратный порядок элементов, не сортируя их значения.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Исходный массив. |
| preserve_keys | true сохраняет числовые ключи, false перенумеровывает. Строковые ключи сохраняются в обоих режимах. |
| Возврат | Новый массив в обратном порядке; значения не меняются. |
| Отказ и диагностика | Неверный тип array — TypeError. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Порядок 10:A, 20:B
- Читать с конца
- B затем A; ключи выбирает preserve_keys
<?php
$items = [10 => 'A', 20 => 'B'];
echo json_encode(array_reverse($items)), "
";
echo json_encode(array_reverse($items, true)), "
";
Ожидаемый результат
["B","A"]
{"20":"B","10":"A"}
Обратный порядок ничего не говорит о цене, дате или алфавите.
<?php
$log = ['evt-1' => 'open', 'evt-2' => 'save', 'evt-3' => 'close'];
foreach (array_reverse($log) as $id => $event) {
echo $id, ':', $event, "
";
}
Ожидаемый результат
evt-3:close
evt-2:save
evt-1:open
Такой приём корректен, если исходный журнал уже расположен хронологически. Смешанные даты нужно сначала сортировать.
Нюансы и выбор. Для настоящего убывания по значениям нужна rsort/arsort. Reverse не выполняет сравнения.
Сравните: rsort, arsort, array_slice. Выбрать операцию по задаче.
array_padДополнить короткий ряд до нужного размера заданным значением.
PHP 4+ · standard
array_pad(array $array, int $length, mixed $value): arrayДополнить короткий ряд до нужного размера заданным значением.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Исходный массив. |
| length | Целевой размер по модулю; положительное число дополняет справа, отрицательное — слева. Если размер уже достаточен, ничего не удаляется. |
| value | Каждое добавленное значение. Объект остаётся одним и тем же экземпляром, а не клонируется. |
| Возврат | Новый массив. При дополнении числовые ключи перенумеровываются, строковые сохраняются. |
| Отказ и диагностика | Предельный размер ограничен возможностями массива и памятью. До PHP 8.3 за один вызов разрешалось добавить не более 1 048 576 элементов; теперь этот отдельный предел снят. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Ряд [7,9]
- Целевой размер 4, дополнение 0 справа
- Получить [7,9,0,0]
<?php
echo json_encode(array_pad([7,9], 4, 0)), "
";
echo json_encode(array_pad([7,9], -4, 0)), "
";
echo json_encode(array_pad([7,9], 1, 0)), "
";
Ожидаемый результат
[7,9,0,0]
[0,0,7,9]
[7,9]
Целевой размер меньше исходного не обрезает вход.
<?php
$measurements = [12];
$cells = array_pad($measurements, 3, null);
foreach ($cells as $value) { echo $value === null ? "нет
" : $value . "
"; }
Ожидаемый результат
12
нет
нет
null здесь означает отсутствие измерения. Ноль значил бы реально измеренный ноль и исказил бы отчёт.
Нюансы и выбор. Не передавайте произвольный размер из запроса без верхнего ограничения. Для создания массива с нуля подходит fill, для обрезки slice.
Сравните: array_fill, array_slice, array_merge. Выбрать операцию по задаче.
array_pushДобавить несколько значений в конец списка.
PHP 4+ · standard
array_push(array &$array, mixed ...$values): intДобавить несколько значений в конец списка.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив. |
| values | Значения в порядке аргументов. Можно не передавать с PHP 7.3 — тогда возвращается текущий размер. |
| Возврат | Новое количество элементов, не новый массив. Существующие ключи сохраняются, новые получают следующий автоматический целочисленный индекс. |
| Отказ и диагностика | PHP 8: неверный тип первого аргумента — TypeError. В старых версиях могла быть warning; не используйте её как контракт современного PHP. |
Знак & перед первым параметром в справочной сигнатуре означает изменение переданного массива. В самом вызове & не пишут: передают переменную, а не временное выражение.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Есть одна накладная под ключом 10.
- Добавить проверку адреса и упаковку после неё.
- Отдельно прочитать число 3 и каждое задание из изменённого tasks.
<?php
$tasks = [10 => 'выписать накладную'];
$size = array_push($tasks, 'проверить адрес', 'подготовить упаковку');
echo 'Заданий после добавления: ', $size, "\n";
foreach ($tasks as $position => $task) {
echo $position, ': ', $task, "\n";
}
Ожидаемый результат
Заданий после добавления: 3
10: выписать накладную
11: проверить адрес
12: подготовить упаковку
Первый аргумент tasks меняется на месте. Два следующих — отдельные новые задания; между собой они сохраняют порядок. В size возвращено количество 3, а реальные задания читаются из tasks. При добавлении в конец старый ключ 10 сохранён, новые получили 11 и 12. Запись tasks = array_push(...) потеряла бы массив, заменив его числом.
<?php
$queue = ["report"];
$new = ["mail", "export"];
array_push($queue, ...$new);
echo implode(",", $queue), "\n";
echo array_push($queue), "\n";
Ожидаемый результат
report,mail,export
3
...$new разворачивает элементы в отдельные аргументы. Пустой набор значений не удаляет очередь.
Нюансы и выбор. Для одного значения обычное $array[] = $value проще и не требует вызова функции. Для вложенного массива без ... добавится один вложенный элемент.
Сравните: array_unshift, array_pop, array_shift, array_splice. Выбрать операцию по задаче.
array_unshiftДобавить несколько значений в начало списка.
PHP 4+ · standard
array_unshift(array &$array, mixed ...$values): intДобавить несколько значений в начало списка.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив. |
| values | Значения в порядке аргументов. Можно не передавать с PHP 7.3 — тогда возвращается текущий размер. |
| Возврат | Новое количество элементов, не новый массив. Числовые ключи перенумеровываются, строковые сохраняются; указатель сбрасывается в начало. |
| Отказ и диагностика | PHP 8: неверный тип первого аргумента — TypeError. В старых версиях могла быть warning; не используйте её как контракт современного PHP. |
Знак & перед первым параметром в справочной сигнатуре означает изменение переданного массива. В самом вызове & не пишут: передают переменную, а не временное выражение.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Есть одна накладная под ключом 10.
- Добавить проверку адреса и упаковку перед ней.
- Отдельно прочитать число 3 и каждое задание из изменённого tasks.
<?php
$tasks = [10 => 'выписать накладную'];
$size = array_unshift($tasks, 'проверить адрес', 'подготовить упаковку');
echo 'Заданий после добавления: ', $size, "\n";
foreach ($tasks as $position => $task) {
echo $position, ': ', $task, "\n";
}
Ожидаемый результат
Заданий после добавления: 3
0: проверить адрес
1: подготовить упаковку
2: выписать накладную
Первый аргумент tasks меняется на месте. Два следующих — отдельные новые задания; между собой они сохраняют порядок. В size возвращено количество 3, а реальные задания читаются из tasks. Добавление в начало перенумеровало числовые ключи: 0,1,2. Запись tasks = array_unshift(...) потеряла бы массив, заменив его числом.
<?php
$queue = ["report"];
$new = ["mail", "export"];
array_unshift($queue, ...$new);
echo implode(",", $queue), "\n";
echo array_unshift($queue), "\n";
Ожидаемый результат
mail,export,report
3
...$new разворачивает элементы в отдельные аргументы. Пустой набор значений не удаляет очередь.
Нюансы и выбор. Частые вставки в начало требуют перемещения/перенумерации числовых элементов. Для большой очереди рассмотрите SplQueue или иной специализированный контейнер.
Сравните: array_push, array_pop, array_shift, array_splice. Выбрать операцию по задаче.
array_popИзвлечь и удалить последний элемент стека.
PHP 4+ · standard
array_pop(array &$array): mixedИзвлечь и удалить последний элемент стека.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Переменная-массив, изменяемая на месте. |
| Возврат | Удалённое значение; для пустого массива null. Указатель сбрасывается в начало. Оставшиеся ключи сохраняются. |
| Отказ и диагностика | В PHP 8 немассивный аргумент даёт TypeError, а не универсальное null. Возврат null может быть удалённым значением либо признаком пустоты. |
Знак & перед первым параметром в справочной сигнатуре означает изменение переданного массива. В самом вызове & не пишут: передают переменную, а не временное выражение.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Три задания: адрес, упаковка, накладная.
- Извлечь накладную из конца.
- Возврат даёт одно задание; tasks хранит два оставшихся.
<?php
$tasks = [10 => 'адрес', 20 => 'упаковка', 30 => 'накладная'];
$task = array_pop($tasks);
echo 'Получено задание: ', $task, "\n";
echo "Осталось:\n";
foreach ($tasks as $position => $remaining) {
echo $position, ': ', $remaining, "\n";
}
Ожидаемый результат
Получено задание: накладная
Осталось:
10: адрес
20: упаковка
Вызов удаляет последнее значение и возвращает только его в task. Дальнейший код мог бы выполнить полученное задание; здесь он сообщает название, затем отдельно читает остаток из tasks. Pop сохранил ключи остатка 10 и 20. Перед выбором из неизвестной очереди проверяют её непустоту; следующий опыт отделяет пустой массив от полезного значения null.
<?php
$items = [null];
while ($items !== []) {
$value = array_pop($items);
echo $value === null ? "Получен null\n" : "Получено значение\n";
}
var_dump(array_pop($items));
Ожидаемый результат
Получен null
NULL
Условие проверяет наличие элементов до удаления. Цикл while (($value = pop(...)) !== null) преждевременно закончился бы на полезном null.
Нюансы и выбор. Для чтения без удаления используйте array_last в PHP 8.5+ или array_key_last и чтение по ключу в прежних версиях.
Сравните: array_shift, array_first, array_last. Выбрать операцию по задаче.
array_shiftИзвлечь и удалить первый элемент очереди.
PHP 4+ · standard
array_shift(array &$array): mixedИзвлечь и удалить первый элемент очереди.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Переменная-массив, изменяемая на месте. |
| Возврат | Удалённое значение; для пустого массива null. Указатель сбрасывается в начало. Оставшиеся числовые ключи перенумеровываются с нуля; строковые сохраняются. |
| Отказ и диагностика | В PHP 8 немассивный аргумент даёт TypeError, а не универсальное null. Возврат null может быть удалённым значением либо признаком пустоты. |
Знак & перед первым параметром в справочной сигнатуре означает изменение переданного массива. В самом вызове & не пишут: передают переменную, а не временное выражение.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Три задания: адрес, упаковка, накладная.
- Извлечь адрес из начала.
- Возврат даёт одно задание; tasks хранит два оставшихся.
<?php
$tasks = [10 => 'адрес', 20 => 'упаковка', 30 => 'накладная'];
$task = array_shift($tasks);
echo 'Получено задание: ', $task, "\n";
echo "Осталось:\n";
foreach ($tasks as $position => $remaining) {
echo $position, ': ', $remaining, "\n";
}
Ожидаемый результат
Получено задание: адрес
Осталось:
0: упаковка
1: накладная
Вызов удаляет первое значение и возвращает только его в task. Дальнейший код мог бы выполнить полученное задание; здесь он сообщает название, затем отдельно читает остаток из tasks. Shift перенумеровал числовые ключи остатка 0 и 1. Перед выбором из неизвестной очереди проверяют её непустоту; следующий опыт отделяет пустой массив от полезного значения null.
<?php
$items = [null];
while ($items !== []) {
$value = array_shift($items);
echo $value === null ? "Получен null\n" : "Получено значение\n";
}
var_dump(array_shift($items));
Ожидаемый результат
Получен null
NULL
Условие проверяет наличие элементов до удаления. Цикл while (($value = pop(...)) !== null) преждевременно закончился бы на полезном null.
Нюансы и выбор. Повторный shift для большой очереди может быть дорогим из-за перенумерации. Если удаление не нужно, используйте foreach; для очереди — SplQueue.
Сравните: array_pop, array_first, array_last. Выбрать операцию по задаче.
array_sumСложить числовые значения, например суммы уже проверенных строк заказа.
PHP 4.0.4+ · standard
array_sum(array $array): int|floatСложить числовые значения, например суммы уже проверенных строк заказа.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Числовые значения; ключи не участвуют. Числовые строки могут преобразовываться, но это не проверка входного формата. |
| Возврат | Целое число или float. Пустой массив даёт 0 — нейтральное слагаемое. |
| Отказ и диагностика | С PHP 8.3 непреобразуемые в число значения вызывают E_WARNING. Раньше массивы/объекты игнорировались, другие значения преобразовывались; теперь объекты с числовым cast, например GMP, могут участвовать в расчёте. |
- Числа 2, 3, 4
- Сложить начиная с 0
- Получить 9
<?php
echo array_sum([2,3,4]), "\n";
echo array_sum([]), "\n";
Ожидаемый результат
9
0
Пустой вход не означает ошибку; бизнес-правило о минимальном числе позиций проверяется отдельно.
<?php
$lineTotals = ['p1' => 19900, 'p2' => 4500];
$itemsTotalKopecks = array_sum($lineTotals);
$deliveryKopecks = 30000;
$payableKopecks = $itemsTotalKopecks + $deliveryKopecks;
echo 'Товары: ', $itemsTotalKopecks, ' коп.', "\n";
echo 'С доставкой: ', $payableKopecks, ' коп.', "\n";
Ожидаемый результат
Товары: 24400 коп.
С доставкой: 54400 коп.
Sum складывает только значения 19900 и 4500; ключи p1/p2 в арифметике не участвуют. Return 24400 сохранён в itemsTotalKopecks, затем обычное + даёт 54400. Здесь уже заданы суммы строк в целых копейках: функция не перемножает price и quantity вложенной записи автоматически.
Нюансы и выбор. Функция не спускается рекурсивно по строкам заказа. Сначала извлеките/рассчитайте нужные числа. Float имеет погрешность, а превышение целочисленного диапазона может изменить тип результата; для точных больших денежных расчётов нужна подходящая числовая модель.
Сравните: array_product, array_reduce, array_column. Выбрать операцию по задаче.
array_productПеремножить числовые значения, например количества вариантов комплектации.
PHP 5.1+ · standard
array_product(array $array): int|floatПеремножить числовые значения, например количества вариантов комплектации.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Числовые значения; ключи не участвуют. Числовые строки могут преобразовываться, но это не проверка входного формата. |
| Возврат | Целое число или float. Пустой массив даёт 1 — нейтральный множитель. |
| Отказ и диагностика | С PHP 8.3 непреобразуемые в число значения вызывают E_WARNING. Раньше массивы/объекты игнорировались, другие значения преобразовывались; теперь объекты с числовым cast, например GMP, могут участвовать в расчёте. |
- Числа 2, 3, 4
- Умножить начиная с 1
- Получить 24
<?php
echo array_product([2,3,4]), "\n";
echo array_product([]), "\n";
Ожидаемый результат
24
1
Пустой вход не означает ошибку; бизнес-правило о минимальном числе позиций проверяется отдельно.
<?php
$choices = ['colors' => 3, 'sizes' => 4, 'packs' => 2];
$variants = array_product($choices);
echo 'Доступно сочетаний: ', $variants, "\n";
$choices['sizes'] = 0;
$variants = array_product($choices);
if ($variants === 0) {
echo "Конструктор недоступен: нет размеров\n";
}
Ожидаемый результат
Доступно сочетаний: 24
Конструктор недоступен: нет размеров
Три независимых выбора дают 3 × 4 × 2 = 24. После нуля в sizes произведение 0 используется в ветке недоступности. Если цвет ограничивает размеры, варианты зависимы и такая формула неверна. Пустой массив дал бы 1 как нейтральный множитель, а не признак готовой комплектации.
Нюансы и выбор. Функция не спускается рекурсивно по строкам заказа. Сначала извлеките/рассчитайте нужные числа. Float имеет погрешность, а превышение целочисленного диапазона может изменить тип результата; для точных больших денежных расчётов нужна подходящая числовая модель.
Сравните: array_sum, array_reduce, array_column. Выбрать операцию по задаче.
array_diff_assocРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Ключ и значение одновременно.
PHP 4.3+ · standard
array_diff_assoc(array $array, array ...$arrays): arrayРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Ключ и значение одновременно.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. Без них допустим вызов с PHP 8: возвращается исходное содержимое. |
| Что совпадает | Ключ и значение одновременно. Встроенное сравнение ключей проверяет одинаковое строковое представление. Значения равны, когда их строковые представления совпадают: 10 и "10" равны, 10 и "010" различаются. Это не строгое сравнение исходных типов. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Вложенные массивы здесь не сравниваются рекурсивно: приведение массива к строке вызывает warning, объект без строкового преобразования — Error. Немассивные входы — TypeError. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Первый массив задаёт кандидатов
- Сверить пары с остальными
- Сохранить пару, если совпадение не найдено ни в одном из остальных массивов
<?php
$a = ["a" => 10, "b" => 20, "c" => 10];
$b = ["a" => "10", "b" => 30, "z" => 10];
echo json_encode(array_diff_assoc($a, $b)), "\n";
Ожидаемый результат
{"b":20,"c":10}
Ключ и значение одновременно. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$new = ['host' => 'mail.local', 'port' => 587, 'tls' => 'on'];
$old = ['host' => 'mail.local', 'port' => 25];
$selected = array_diff_assoc($new, $old);
foreach ($selected as $setting => $value) {
echo "Изменённая или новая настройка: ", $setting, " = ", $value, "\n";
}
Ожидаемый результат
Изменённая или новая настройка: port = 587
Изменённая или новая настройка: tls = on
Для совпадения должны подойти и ключ, и значение одной пары. Host совпадает; port существует, но 587 отличается от 25; tls прежде отсутствовал. Return — словарь выбранных пар из new. Его foreach превращает в строки отчёта; настройки подключения здесь ещё не применяются. Значения сравниваются по строковому представлению: число 25 и строка "25" считались бы совпадением, поэтому это не аудит типов. Удалённые из new поля ищутся отдельным сравнением в обратную сторону.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_diff, array_diff_key, array_udiff, array_unique. Выбрать операцию по задаче.
array_diff_keyРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Только ключи; значения не сравниваются.
PHP 5.1+ · standard
array_diff_key(array $array, array ...$arrays): arrayРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Только ключи; значения не сравниваются.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. Без них допустим вызов с PHP 8: возвращается исходное содержимое. |
| Что совпадает | Только ключи; значения не сравниваются. Встроенное сравнение ключей проверяет одинаковое строковое представление. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Немассивные входы — TypeError. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Первый массив задаёт кандидатов
- Сверить ключи с остальными
- Сохранить пару, если совпадение не найдено ни в одном из остальных массивов
<?php
$a = ["name" => "Ada", "price" => 9];
$b = ["name" => null];
echo json_encode(array_diff_key($a, $b)), "\n";
Ожидаемый результат
{"price":9}
Только ключи; значения не сравниваются. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$incoming = ['name' => 'Анна', 'note' => 'Позвонить', 'role' => 'admin'];
$fields = ['name' => true, 'note' => true];
$selected = array_diff_key($incoming, $fields);
foreach ($selected as $field => $value) {
echo "Неизвестное поле: ", $field, " = ", $value, "\n";
}
Ожидаемый результат
Неизвестное поле: role = admin
Словарь fields использует только ключи: значения true — заполнители и с «Анна» не сравниваются. Diff оставляет неизвестное role и его исходное значение admin, чтобы объяснить отказ пользователю. Функция не сохраняет данные и не назначает права. Сравниваются одинаковые имена ключей. Значение null в маске тоже обозначало бы присутствующий ключ.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_diff, array_diff_assoc, array_udiff, array_unique. Выбрать операцию по задаче.
array_diff_uassocРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Ключ и значение одновременно.
PHP 5+ · standard
array_diff_uassoc(array $array, array ...$arrays, callable $key_compare_func): arrayРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Ключ и значение одновременно.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. После массивов последним передаётся callback сравнения ключей. Не считайте его ещё одним массивом. В PHP 8.5.11 допускается только исходный массив и callback: результат сохраняет исходное содержимое. |
| Что совпадает | Ключ и значение одновременно. Значения равны, когда их строковые представления совпадают: 10 и "10" равны, 10 и "010" различаются. Это не строгое сравнение исходных типов. |
| key_compare_func | callback(keyA, keyB): int; 0 означает равные ключи. strcasecmp ниже сравнивает ASCII-регистр без различий. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Ошибки callback распространяются наружу; он обязан возвращать целое сравнение, float приводится к int и может ошибочно стать 0. Вложенные массивы здесь не сравниваются рекурсивно: приведение массива к строке вызывает warning, объект без строкового преобразования — Error. Немассивные входы — TypeError. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. strcasecmp — встроенное сравнение двух строк без учёта ASCII-регистра.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Первый массив задаёт кандидатов
- Сверить пары с остальными
- Сохранить пару, если совпадение не найдено ни в одном из остальных массивов
<?php
$a = ["A" => 10, "B" => 20, "C" => 10];
$b = ["a" => "10", "b" => 30, "z" => 10];
echo json_encode(array_diff_uassoc($a, $b, "strcasecmp")), "\n";
Ожидаемый результат
{"B":20,"C":10}
Ключ и значение одновременно. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$new = ['host' => 'mail.local', 'port' => 587, 'tls' => 'on'];
$old = ['HOST' => 'mail.local', 'PORT' => 25];
$selected = array_diff_uassoc($new, $old, "strcasecmp");
foreach ($selected as $setting => $value) {
echo "Изменённая или новая настройка: ", $setting, " = ", $value, "\n";
}
Ожидаемый результат
Изменённая или новая настройка: port = 587
Изменённая или новая настройка: tls = on
Для совпадения должны подойти и ключ, и значение одной пары. Host совпадает; port существует, но 587 отличается от 25; tls прежде отсутствовал. Return — словарь выбранных пар из new. Его foreach превращает в строки отчёта; настройки подключения здесь ещё не применяются. Ключи сравнивает strcasecmp без ASCII-регистра, а значения — встроенное строковое представление. Удалённые из new поля ищутся отдельным сравнением в обратную сторону.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Порядок callback не фиксирован; не рассчитывайте на вызов строго слева направо по исходному списку. Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_diff, array_diff_assoc, array_diff_key, array_udiff, array_unique. Выбрать операцию по задаче.
array_diff_ukeyРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Только ключи; значения не сравниваются.
PHP 5.1+ · standard
array_diff_ukey(array $array, array ...$arrays, callable $key_compare_func): arrayРазность массивов: оставить пары первого входа, для которых совпадение не найдено ни в одном из остальных массивов. Только ключи; значения не сравниваются.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. После массивов последним передаётся callback сравнения ключей. Не считайте его ещё одним массивом. В PHP 8.5.11 допускается только исходный массив и callback: результат сохраняет исходное содержимое. |
| Что совпадает | Только ключи; значения не сравниваются. |
| key_compare_func | callback(keyA, keyB): int; 0 означает равные ключи. strcasecmp ниже сравнивает ASCII-регистр без различий. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Ошибки callback распространяются наружу; он обязан возвращать целое сравнение, float приводится к int и может ошибочно стать 0. Немассивные входы — TypeError. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. strcasecmp — встроенное сравнение двух строк без учёта ASCII-регистра.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Первый массив задаёт кандидатов
- Сверить ключи с остальными
- Сохранить пару, если совпадение не найдено ни в одном из остальных массивов
<?php
$a = ["Name" => "Ada", "Price" => 9];
$b = ["name" => null];
echo json_encode(array_diff_ukey($a, $b, "strcasecmp")), "\n";
Ожидаемый результат
{"Price":9}
Только ключи; значения не сравниваются. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$incoming = ['name' => 'Анна', 'note' => 'Позвонить', 'role' => 'admin'];
$fields = ['NAME' => true, 'NOTE' => true];
$selected = array_diff_ukey($incoming, $fields, "strcasecmp");
foreach ($selected as $field => $value) {
echo "Неизвестное поле: ", $field, " = ", $value, "\n";
}
Ожидаемый результат
Неизвестное поле: role = admin
Словарь fields использует только ключи: значения true — заполнители и с «Анна» не сравниваются. Diff оставляет неизвестное role и его исходное значение admin, чтобы объяснить отказ пользователю. Функция не сохраняет данные и не назначает права. Здесь договор явно допускает ASCII-регистр имён: strcasecmp возвращает 0 для name/NAME. Это готовая функция сравнения двух строк; строка "strcasecmp" передаёт её как callback.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Порядок callback не фиксирован; не рассчитывайте на вызов строго слева направо по исходному списку. Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_diff, array_diff_assoc, array_diff_key, array_udiff, array_unique. Выбрать операцию по задаче.
array_udiffВычислить разность по собственному правилу значений.
PHP 5+ · standard
array_udiff(array $array, array ...$arrays, callable $value_compare_func): arrayВычислить разность по собственному правилу значений.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array / array1 | Первый массив задаёт возвращаемые пары и порядок. |
| arrays | Остальные массивы, затем callback-функции. Сохраняется элемент, для которого совпадение не найдено ни в одном из остальных массивов. В PHP 8.5.11 допустимо не передавать дополнительные массивы: с нужными callback возвращается содержимое первого. |
| value_compare_func | callback(valueA, valueB): int. Должен уметь сравнить любые два элемента любого из входов в любом порядке. |
| Возврат | Новый массив из подходящих элементов первого входа; ключи, значения и их исходный порядок сохранены. |
| Отказ и диагностика | Float-результат компаратора приводится к int, дробь меньше 1 превратится в 0. Неподходящие типы входных элементов и ошибки callback могут привести к исключению. Не изменяйте сравниваемые данные из callback. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. abs возвращает модуль числа: -3 и 3 дают одинаковое значение 3.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Кандидаты -3, 8, 3
- Сравнить модули со значением 3
- Сохранить выбранные исходные пары, а не модули
<?php
$a = ["a" => -3, "b" => 8, "c" => 3];
$b = ["other" => 3];
$compare = function ($a, $b) { return abs($a) <=> abs($b); };
echo json_encode(array_udiff($a, $b, $compare)), "\n";
Ожидаемый результат
{"b":8}
Равенство выражено возвратом 0. Модуль нужен только для сравнения, исходные числа не заменяются.
Первый опыт уже показал три исхода компаратора: меньше, равно, больше. Теперь параметрами будут записи-массивы. Форма каждой записи проверена заранее; нельзя предполагать, что left всегда из local, а right всегда из remote.
<?php
$local = [['id' => 12, 'name' => 'Локальная карточка'], ['id' => 25, 'name' => 'Новый товар']];
$remote = [['id' => 12, 'name' => 'Иное название']];
$compareId = function ($left, $right) {
return $left["id"] <=> $right["id"];
};
$selected = array_udiff($local, $remote, $compareId);
foreach ($selected as $record) {
echo "ID ", $record["id"], ": ", $record["name"], "\n";
}
Ожидаемый результат
ID 25: Новый товар
Каждый параметр callback — одна запись с int-полем id. Возврат left[id]<=>right[id] равен 0 для одинакового ID независимо от name. Алгоритм получает этот знак для сравнения; selected получает массив подходящих записей local. ID 12 уже присутствует в remote; ID 25 отсутствует и попадает в план добавления. Ключи исходных списков не являются критерием. Такая операция не проверяет уникальность ID и не синхронизирует базу сама.
Нюансы и выбор. Внутри сравнения массивы могут предварительно сортироваться, поэтому нельзя предполагать: $a всегда из local, $b всегда из remote. Нужен согласованный полный порядок (транзитивность, противоположные знаки при обмене аргументов), не функция «похож/не похож». Обход одноуровневый; callback сам выбирает поля вложенных значений. Для больших наборов с точным уникальным ID явный индекс нередко проще повторных сравнений.
Сравните: array_diff, array_diff_assoc, array_udiff_assoc, array_udiff_uassoc. Выбрать операцию по задаче.
Реальная причина ошибки из вопроса о пропавших элементах: callback отдавал только 0/1 и не задавал согласованного порядка двух аргументов. Для отбора по одному признаку нужен array_filter; компаратор здесь обязан сравнить оба входа. Ответы обсуждения не служат нормативным правилом; договор проверен по PHP Manual.
array_udiff_assocВычислить разность по собственному правилу значений с проверкой ключа.
PHP 5+ · standard
array_udiff_assoc(array $array, array ...$arrays, callable $value_compare_func): arrayВычислить разность по собственному правилу значений с проверкой ключа.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array / array1 | Первый массив задаёт возвращаемые пары и порядок. |
| arrays | Остальные массивы, затем callback-функции. Сохраняется элемент, для которого совпадение не найдено ни в одном из остальных массивов. В PHP 8.5.11 допустимо не передавать дополнительные массивы: с нужными callback возвращается содержимое первого. |
| value_compare_func | callback(valueA, valueB): int. Должен уметь сравнить любые два элемента любого из входов в любом порядке. |
| Ключи | Пара должна иметь совпавший ключ по встроенному правилу; одного равенства значений недостаточно. |
| Возврат | Новый массив из подходящих элементов первого входа; ключи, значения и их исходный порядок сохранены. |
| Отказ и диагностика | Float-результат компаратора приводится к int, дробь меньше 1 превратится в 0. Неподходящие типы входных элементов и ошибки callback могут привести к исключению. Не изменяйте сравниваемые данные из callback. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. abs возвращает модуль числа: -3 и 3 дают одинаковое значение 3.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Кандидаты -3, 8, 3
- Сравнить модули со значением 3 и ключи
- Сохранить выбранные исходные пары, а не модули
<?php
$a = ["a" => -3, "b" => 8, "c" => 3];
$b = ["a" => 3];
$compare = function ($a, $b) { return abs($a) <=> abs($b); };
echo json_encode(array_udiff_assoc($a, $b, $compare)), "\n";
Ожидаемый результат
{"b":8,"c":3}
Равенство выражено возвратом 0. Модуль нужен только для сравнения, исходные числа не заменяются.
Первый опыт уже показал три исхода компаратора: меньше, равно, больше. Теперь параметрами будут записи-массивы. Форма каждой записи проверена заранее; нельзя предполагать, что left всегда из local, а right всегда из remote.
<?php
$local = ['sku-a' => ['revision' => 2, 'label' => 'Карточка A'], 'sku-b' => ['revision' => 3, 'label' => 'Карточка B']];
$remote = ['sku-a' => ['revision' => 2, 'label' => 'Другое название A'], 'sku-b' => ['revision' => 1, 'label' => 'Старое название B']];
$compareRevision = function ($left, $right) {
return $left["revision"] <=> $right["revision"];
};
$selected = array_udiff_assoc($local, $remote, $compareRevision);
foreach ($selected as $sku => $record) {
echo $sku, ": ", $record["label"], ", версия ", $record["revision"], "\n";
}
Ожидаемый результат
sku-b: Карточка B, версия 3
Callback получает две целые записи, читает revision и возвращает знак сравнения. Для версий 2/2 это 0, для 3/1 — 1; алгоритм может дать их в обратном порядке или из одного входа. Дополнительно проверяются ключи по встроенному правилу. Для sku-a совпадают ключ и версия; для sku-b версия отличается. Return всей операции — выбранные исходные записи local, поэтому выводится его label, а не удалённый. Поле label намеренно не входит в критерий: равная версия здесь не доказывает побайтовое равенство всей карточки.
Нюансы и выбор. Внутри сравнения массивы могут предварительно сортироваться, поэтому нельзя предполагать: $a всегда из local, $b всегда из remote. Нужен согласованный полный порядок (транзитивность, противоположные знаки при обмене аргументов), не функция «похож/не похож». Обход одноуровневый; callback сам выбирает поля вложенных значений. Для больших наборов с точным уникальным ID явный индекс нередко проще повторных сравнений.
Сравните: array_diff, array_diff_assoc, array_udiff, array_udiff_uassoc. Выбрать операцию по задаче.
Реальная причина ошибки из вопроса о пропавших элементах: callback отдавал только 0/1 и не задавал согласованного порядка двух аргументов. Для отбора по одному признаку нужен array_filter; компаратор здесь обязан сравнить оба входа. Ответы обсуждения не служат нормативным правилом; договор проверен по PHP Manual.
array_udiff_uassocВычислить разность по собственному правилу значений с проверкой ключа.
PHP 5+ · standard
array_udiff_uassoc(array $array, array ...$arrays, callable $value_compare_func, callable $key_compare_func): arrayВычислить разность по собственному правилу значений с проверкой ключа.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array / array1 | Первый массив задаёт возвращаемые пары и порядок. |
| arrays | Остальные массивы, затем callback-функции. Сохраняется элемент, для которого совпадение не найдено ни в одном из остальных массивов. В PHP 8.5.11 допустимо не передавать дополнительные массивы: с нужными callback возвращается содержимое первого. |
| value_compare_func | callback(valueA, valueB): int. Должен уметь сравнить любые два элемента любого из входов в любом порядке. |
| Ключи | Последний key_compare_func(keyA,keyB): int сравнивает ключи. Порядок callback: сначала значения, потом ключи. |
| Возврат | Новый массив из подходящих элементов первого входа; ключи, значения и их исходный порядок сохранены. |
| Отказ и диагностика | Float-результат компаратора приводится к int, дробь меньше 1 превратится в 0. Неподходящие типы входных элементов и ошибки callback могут привести к исключению. Не изменяйте сравниваемые данные из callback. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. abs возвращает модуль числа: -3 и 3 дают одинаковое значение 3. strcasecmp во втором callback сравнивает ключи без учёта ASCII-регистра.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Кандидаты -3, 8, 3
- Сравнить модули со значением 3 и ключи
- Сохранить выбранные исходные пары, а не модули
<?php
$a = ["A" => -3, "B" => 8, "C" => 3];
$b = ["a" => 3];
$compare = function ($a, $b) { return abs($a) <=> abs($b); };
echo json_encode(array_udiff_uassoc($a, $b, $compare, "strcasecmp")), "\n";
Ожидаемый результат
{"B":8,"C":3}
Равенство выражено возвратом 0. Модуль нужен только для сравнения, исходные числа не заменяются.
Первый опыт уже показал три исхода компаратора: меньше, равно, больше. Теперь параметрами будут записи-массивы. Форма каждой записи проверена заранее; нельзя предполагать, что left всегда из local, а right всегда из remote.
<?php
$local = ['SKU-A' => ['revision' => 2, 'label' => 'Карточка A'], 'SKU-B' => ['revision' => 3, 'label' => 'Карточка B']];
$remote = ['sku-a' => ['revision' => 2, 'label' => 'Другое название A'], 'sku-b' => ['revision' => 1, 'label' => 'Старое название B']];
$compareRevision = function ($left, $right) {
return $left["revision"] <=> $right["revision"];
};
$selected = array_udiff_uassoc($local, $remote, $compareRevision, "strcasecmp");
foreach ($selected as $sku => $record) {
echo $sku, ": ", $record["label"], ", версия ", $record["revision"], "\n";
}
Ожидаемый результат
SKU-B: Карточка B, версия 3
Callback получает две целые записи, читает revision и возвращает знак сравнения. Для версий 2/2 это 0, для 3/1 — 1; алгоритм может дать их в обратном порядке или из одного входа. Дополнительно проверяются ключи вторым callback strcasecmp; сначала передан callback значений, потом ключей. Для sku-a совпадают ключ и версия; для sku-b версия отличается. Return всей операции — выбранные исходные записи local, поэтому выводится его label, а не удалённый. Поле label намеренно не входит в критерий: равная версия здесь не доказывает побайтовое равенство всей карточки.
Нюансы и выбор. Внутри сравнения массивы могут предварительно сортироваться, поэтому нельзя предполагать: $a всегда из local, $b всегда из remote. Нужен согласованный полный порядок (транзитивность, противоположные знаки при обмене аргументов), не функция «похож/не похож». Обход одноуровневый; callback сам выбирает поля вложенных значений. Для больших наборов с точным уникальным ID явный индекс нередко проще повторных сравнений.
Сравните: array_diff, array_diff_assoc, array_udiff, array_udiff_assoc. Выбрать операцию по задаче.
Реальная причина ошибки из вопроса о пропавших элементах: callback отдавал только 0/1 и не задавал согласованного порядка двух аргументов. Для отбора по одному признаку нужен array_filter; компаратор здесь обязан сравнить оба входа. Ответы обсуждения не служат нормативным правилом; договор проверен по PHP Manual.
array_intersect_assocПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Ключ и значение одновременно.
PHP 4.3+ · standard
array_intersect_assoc(array $array, array ...$arrays): arrayПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Ключ и значение одновременно.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. Без них допустим вызов с PHP 8: возвращается исходное содержимое. |
| Что совпадает | Ключ и значение одновременно. Встроенное сравнение ключей проверяет одинаковое строковое представление. Значения равны, когда их строковые представления совпадают: 10 и "10" равны, 10 и "010" различаются. Это не строгое сравнение исходных типов. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Вложенные массивы здесь не сравниваются рекурсивно: приведение массива к строке вызывает warning, объект без строкового преобразования — Error. Немассивные входы — TypeError. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Первый массив задаёт кандидатов
- Сверить пары с остальными
- Сохранить пару, если совпадение найдено в каждом из остальных массивов
<?php
$a = ["a" => 10, "b" => 20, "c" => 10];
$b = ["a" => "10", "b" => 30, "z" => 10];
echo json_encode(array_intersect_assoc($a, $b)), "\n";
Ожидаемый результат
{"a":10}
Ключ и значение одновременно. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$new = ['host' => 'mail.local', 'port' => 587, 'tls' => 'on'];
$old = ['host' => 'mail.local', 'port' => 25];
$selected = array_intersect_assoc($new, $old);
foreach ($selected as $setting => $value) {
echo "Неизменившаяся настройка: ", $setting, " = ", $value, "\n";
}
Ожидаемый результат
Неизменившаяся настройка: host = mail.local
Для совпадения должны подойти и ключ, и значение одной пары. Host совпадает; port существует, но 587 отличается от 25; tls прежде отсутствовал. Return — словарь выбранных пар из new. Его foreach превращает в строки отчёта; настройки подключения здесь ещё не применяются. Значения сравниваются по строковому представлению: число 25 и строка "25" считались бы совпадением, поэтому это не аудит типов. Удалённые из new поля ищутся отдельным сравнением в обратную сторону.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_intersect, array_intersect_key, array_uintersect, array_unique. Выбрать операцию по задаче.
array_intersect_keyПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Только ключи; значения не сравниваются.
PHP 5.1+ · standard
array_intersect_key(array $array, array ...$arrays): arrayПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Только ключи; значения не сравниваются.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. Без них допустим вызов с PHP 8: возвращается исходное содержимое. |
| Что совпадает | Только ключи; значения не сравниваются. Встроенное сравнение ключей проверяет одинаковое строковое представление. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Немассивные входы — TypeError. |
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Первый массив задаёт кандидатов
- Сверить ключи с остальными
- Сохранить пару, если совпадение найдено в каждом из остальных массивов
<?php
$a = ["name" => "Ada", "price" => 9];
$b = ["name" => null];
echo json_encode(array_intersect_key($a, $b)), "\n";
Ожидаемый результат
{"name":"Ada"}
Только ключи; значения не сравниваются. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$incoming = ['name' => 'Анна', 'note' => 'Позвонить', 'role' => 'admin'];
$fields = ['name' => true, 'note' => true];
$selected = array_intersect_key($incoming, $fields);
foreach ($selected as $field => $value) {
echo "Разрешённое поле: ", $field, " = ", $value, "\n";
}
Ожидаемый результат
Разрешённое поле: name = Анна
Разрешённое поле: note = Позвонить
Словарь fields использует только ключи: значения true — заполнители и с «Анна» не сравниваются. Intersect оставляет name и note с исходными значениями, которые далее можно проверять по типу и длине. Функция не сохраняет данные и не назначает права. Сравниваются одинаковые имена ключей. Значение null в маске тоже обозначало бы присутствующий ключ.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_intersect, array_intersect_assoc, array_uintersect, array_unique. Выбрать операцию по задаче.
array_intersect_uassocПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Ключ и значение одновременно.
PHP 5+ · standard
array_intersect_uassoc(array $array, array ...$arrays, callable $key_compare_func): arrayПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Ключ и значение одновременно.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. После массивов последним передаётся callback сравнения ключей. Не считайте его ещё одним массивом. В PHP 8.5.11 допускается только исходный массив и callback: результат сохраняет исходное содержимое. |
| Что совпадает | Ключ и значение одновременно. Значения равны, когда их строковые представления совпадают: 10 и "10" равны, 10 и "010" различаются. Это не строгое сравнение исходных типов. |
| key_compare_func | callback(keyA, keyB): int; 0 означает равные ключи. strcasecmp ниже сравнивает ASCII-регистр без различий. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Ошибки callback распространяются наружу; он обязан возвращать целое сравнение, float приводится к int и может ошибочно стать 0. Вложенные массивы здесь не сравниваются рекурсивно: приведение массива к строке вызывает warning, объект без строкового преобразования — Error. Немассивные входы — TypeError. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. strcasecmp — встроенное сравнение двух строк без учёта ASCII-регистра.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Первый массив задаёт кандидатов
- Сверить пары с остальными
- Сохранить пару, если совпадение найдено в каждом из остальных массивов
<?php
$a = ["A" => 10, "B" => 20, "C" => 10];
$b = ["a" => "10", "b" => 30, "z" => 10];
echo json_encode(array_intersect_uassoc($a, $b, "strcasecmp")), "\n";
Ожидаемый результат
{"A":10}
Ключ и значение одновременно. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$new = ['host' => 'mail.local', 'port' => 587, 'tls' => 'on'];
$old = ['HOST' => 'mail.local', 'PORT' => 25];
$selected = array_intersect_uassoc($new, $old, "strcasecmp");
foreach ($selected as $setting => $value) {
echo "Неизменившаяся настройка: ", $setting, " = ", $value, "\n";
}
Ожидаемый результат
Неизменившаяся настройка: host = mail.local
Для совпадения должны подойти и ключ, и значение одной пары. Host совпадает; port существует, но 587 отличается от 25; tls прежде отсутствовал. Return — словарь выбранных пар из new. Его foreach превращает в строки отчёта; настройки подключения здесь ещё не применяются. Ключи сравнивает strcasecmp без ASCII-регистра, а значения — встроенное строковое представление. Удалённые из new поля ищутся отдельным сравнением в обратную сторону.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Порядок callback не фиксирован; не рассчитывайте на вызов строго слева направо по исходному списку. Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_intersect, array_intersect_assoc, array_intersect_key, array_uintersect, array_unique. Выбрать операцию по задаче.
array_intersect_ukeyПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Только ключи; значения не сравниваются.
PHP 5.1+ · standard
array_intersect_ukey(array $array, array ...$arrays, callable $key_compare_func): arrayПересечение массивов: оставить пары первого входа, для которых совпадение найдено в каждом из остальных массивов. Только ключи; значения не сравниваются.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Первый массив — источник возвращаемых ключей, значений и порядка. |
| arrays | Остальные массивы для сравнения. После массивов последним передаётся callback сравнения ключей. Не считайте его ещё одним массивом. В PHP 8.5.11 допускается только исходный массив и callback: результат сохраняет исходное содержимое. |
| Что совпадает | Только ключи; значения не сравниваются. |
| key_compare_func | callback(keyA, keyB): int; 0 означает равные ключи. strcasecmp ниже сравнивает ASCII-регистр без различий. |
| Возврат | Новый массив с исходными ключами/значениями/порядком первого аргумента; повторы подходящих значений не убираются. |
| Отказ и диагностика | Ошибки callback распространяются наружу; он обязан возвращать целое сравнение, float приводится к int и может ошибочно стать 0. Немассивные входы — TypeError. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. strcasecmp — встроенное сравнение двух строк без учёта ASCII-регистра.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Первый массив задаёт кандидатов
- Сверить ключи с остальными
- Сохранить пару, если совпадение найдено в каждом из остальных массивов
<?php
$a = ["Name" => "Ada", "Price" => 9];
$b = ["name" => null];
echo json_encode(array_intersect_ukey($a, $b, "strcasecmp")), "\n";
Ожидаемый результат
{"Name":"Ada"}
Только ключи; значения не сравниваются. Ключи результата взяты из $a.
Теперь применим правило первого опыта к данным задачи. Первый массив задаёт, какие значения и ключи можно вернуть. Следующие массивы служат только для сравнения; они не дополняют результат новыми записями.
<?php
$incoming = ['name' => 'Анна', 'note' => 'Позвонить', 'role' => 'admin'];
$fields = ['NAME' => true, 'NOTE' => true];
$selected = array_intersect_ukey($incoming, $fields, "strcasecmp");
foreach ($selected as $field => $value) {
echo "Разрешённое поле: ", $field, " = ", $value, "\n";
}
Ожидаемый результат
Разрешённое поле: name = Анна
Разрешённое поле: note = Позвонить
Словарь fields использует только ключи: значения true — заполнители и с «Анна» не сравниваются. Intersect оставляет name и note с исходными значениями, которые далее можно проверять по типу и длине. Функция не сохраняет данные и не назначает права. Здесь договор явно допускает ASCII-регистр имён: strcasecmp возвращает 0 для name/NAME. Это готовая функция сравнения двух строк; строка "strcasecmp" передаёт её как callback.
Нюансы и выбор. Проверяется один уровень. Для вложенной записи выберите конкретное поле или собственный компаратор; не подменяйте структуру строкой "Array". Порядок callback не фиксирован; не рассчитывайте на вызов строго слева направо по исходному списку. Если нужна JSON-последовательность, явный array_values допустим только когда исходные ключи не несут смысла.
Сравните: array_intersect, array_intersect_assoc, array_intersect_key, array_uintersect, array_unique. Выбрать операцию по задаче.
array_uintersectВычислить пересечение по собственному правилу значений.
PHP 5+ · standard
array_uintersect(array $array, array ...$arrays, callable $value_compare_func): arrayВычислить пересечение по собственному правилу значений.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array / array1 | Первый массив задаёт возвращаемые пары и порядок. |
| arrays | Остальные массивы, затем callback-функции. Сохраняется элемент, для которого совпадение найдено в каждом из остальных массивов. В PHP 8.5.11 допустимо не передавать дополнительные массивы: с нужными callback возвращается содержимое первого. |
| value_compare_func | callback(valueA, valueB): int. Должен уметь сравнить любые два элемента любого из входов в любом порядке. |
| Возврат | Новый массив из подходящих элементов первого входа; ключи, значения и их исходный порядок сохранены. |
| Отказ и диагностика | Float-результат компаратора приводится к int, дробь меньше 1 превратится в 0. Неподходящие типы входных элементов и ошибки callback могут привести к исключению. Не изменяйте сравниваемые данные из callback. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. abs возвращает модуль числа: -3 и 3 дают одинаковое значение 3.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Кандидаты -3, 8, 3
- Сравнить модули со значением 3
- Сохранить выбранные исходные пары, а не модули
<?php
$a = ["a" => -3, "b" => 8, "c" => 3];
$b = ["other" => 3];
$compare = function ($a, $b) { return abs($a) <=> abs($b); };
echo json_encode(array_uintersect($a, $b, $compare)), "\n";
Ожидаемый результат
{"a":-3,"c":3}
Равенство выражено возвратом 0. Модуль нужен только для сравнения, исходные числа не заменяются.
Первый опыт уже показал три исхода компаратора: меньше, равно, больше. Теперь параметрами будут записи-массивы. Форма каждой записи проверена заранее; нельзя предполагать, что left всегда из local, а right всегда из remote.
<?php
$local = [['id' => 12, 'name' => 'Локальная карточка'], ['id' => 25, 'name' => 'Новый товар']];
$remote = [['id' => 12, 'name' => 'Иное название']];
$compareId = function ($left, $right) {
return $left["id"] <=> $right["id"];
};
$selected = array_uintersect($local, $remote, $compareId);
foreach ($selected as $record) {
echo "ID ", $record["id"], ": ", $record["name"], "\n";
}
Ожидаемый результат
ID 12: Локальная карточка
Каждый параметр callback — одна запись с int-полем id. Возврат left[id]<=>right[id] равен 0 для одинакового ID независимо от name. Алгоритм получает этот знак для сравнения; selected получает массив подходящих записей local. ID 12 есть в обоих входах и попадает в отчёт, причём имя взято из local. Ключи исходных списков не являются критерием. Такая операция не проверяет уникальность ID и не синхронизирует базу сама.
Нюансы и выбор. Внутри сравнения массивы могут предварительно сортироваться, поэтому нельзя предполагать: $a всегда из local, $b всегда из remote. Нужен согласованный полный порядок (транзитивность, противоположные знаки при обмене аргументов), не функция «похож/не похож». Обход одноуровневый; callback сам выбирает поля вложенных значений. Для больших наборов с точным уникальным ID явный индекс нередко проще повторных сравнений.
Сравните: array_intersect, array_intersect_assoc, array_uintersect_assoc, array_uintersect_uassoc. Выбрать операцию по задаче.
Реальная причина ошибки из вопроса о пропавших элементах: callback отдавал только 0/1 и не задавал согласованного порядка двух аргументов. Для отбора по одному признаку нужен array_filter; компаратор здесь обязан сравнить оба входа. Ответы обсуждения не служат нормативным правилом; договор проверен по PHP Manual.
array_uintersect_assocВычислить пересечение по собственному правилу значений с проверкой ключа.
PHP 5+ · standard
array_uintersect_assoc(array $array, array ...$arrays, callable $value_compare_func): arrayВычислить пересечение по собственному правилу значений с проверкой ключа.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array / array1 | Первый массив задаёт возвращаемые пары и порядок. |
| arrays | Остальные массивы, затем callback-функции. Сохраняется элемент, для которого совпадение найдено в каждом из остальных массивов. В PHP 8.5.11 допустимо не передавать дополнительные массивы: с нужными callback возвращается содержимое первого. |
| value_compare_func | callback(valueA, valueB): int. Должен уметь сравнить любые два элемента любого из входов в любом порядке. |
| Ключи | Пара должна иметь совпавший ключ по встроенному правилу; одного равенства значений недостаточно. |
| Возврат | Новый массив из подходящих элементов первого входа; ключи, значения и их исходный порядок сохранены. |
| Отказ и диагностика | Float-результат компаратора приводится к int, дробь меньше 1 превратится в 0. Неподходящие типы входных элементов и ошибки callback могут привести к исключению. Не изменяйте сравниваемые данные из callback. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. abs возвращает модуль числа: -3 и 3 дают одинаковое значение 3.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Кандидаты -3, 8, 3
- Сравнить модули со значением 3 и ключи
- Сохранить выбранные исходные пары, а не модули
<?php
$a = ["a" => -3, "b" => 8, "c" => 3];
$b = ["a" => 3];
$compare = function ($a, $b) { return abs($a) <=> abs($b); };
echo json_encode(array_uintersect_assoc($a, $b, $compare)), "\n";
Ожидаемый результат
{"a":-3}
Равенство выражено возвратом 0. Модуль нужен только для сравнения, исходные числа не заменяются.
Первый опыт уже показал три исхода компаратора: меньше, равно, больше. Теперь параметрами будут записи-массивы. Форма каждой записи проверена заранее; нельзя предполагать, что left всегда из local, а right всегда из remote.
<?php
$local = ['sku-a' => ['revision' => 2, 'label' => 'Карточка A'], 'sku-b' => ['revision' => 3, 'label' => 'Карточка B']];
$remote = ['sku-a' => ['revision' => 2, 'label' => 'Другое название A'], 'sku-b' => ['revision' => 1, 'label' => 'Старое название B']];
$compareRevision = function ($left, $right) {
return $left["revision"] <=> $right["revision"];
};
$selected = array_uintersect_assoc($local, $remote, $compareRevision);
foreach ($selected as $sku => $record) {
echo $sku, ": ", $record["label"], ", версия ", $record["revision"], "\n";
}
Ожидаемый результат
sku-a: Карточка A, версия 2
Callback получает две целые записи, читает revision и возвращает знак сравнения. Для версий 2/2 это 0, для 3/1 — 1; алгоритм может дать их в обратном порядке или из одного входа. Дополнительно проверяются ключи по встроенному правилу. Для sku-a совпадают ключ и версия; для sku-b версия отличается. Return всей операции — выбранные исходные записи local, поэтому выводится его label, а не удалённый. Поле label намеренно не входит в критерий: равная версия здесь не доказывает побайтовое равенство всей карточки.
Нюансы и выбор. Внутри сравнения массивы могут предварительно сортироваться, поэтому нельзя предполагать: $a всегда из local, $b всегда из remote. Нужен согласованный полный порядок (транзитивность, противоположные знаки при обмене аргументов), не функция «похож/не похож». Обход одноуровневый; callback сам выбирает поля вложенных значений. Для больших наборов с точным уникальным ID явный индекс нередко проще повторных сравнений.
Сравните: array_intersect, array_intersect_assoc, array_uintersect, array_uintersect_uassoc. Выбрать операцию по задаче.
Реальная причина ошибки из вопроса о пропавших элементах: callback отдавал только 0/1 и не задавал согласованного порядка двух аргументов. Для отбора по одному признаку нужен array_filter; компаратор здесь обязан сравнить оба входа. Ответы обсуждения не служат нормативным правилом; договор проверен по PHP Manual.
array_uintersect_uassocВычислить пересечение по собственному правилу значений с проверкой ключа.
PHP 5+ · standard
array_uintersect_uassoc(array $array1, array ...$arrays, callable $value_compare_func, callable $key_compare_func): arrayВычислить пересечение по собственному правилу значений с проверкой ключа.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array / array1 | Первый массив задаёт возвращаемые пары и порядок. |
| arrays | Остальные массивы, затем callback-функции. Сохраняется элемент, для которого совпадение найдено в каждом из остальных массивов. В PHP 8.5.11 допустимо не передавать дополнительные массивы: с нужными callback возвращается содержимое первого. |
| value_compare_func | callback(valueA, valueB): int. Должен уметь сравнить любые два элемента любого из входов в любом порядке. |
| Ключи | Последний key_compare_func(keyA,keyB): int сравнивает ключи. Порядок callback: сначала значения, потом ключи. |
| Возврат | Новый массив из подходящих элементов первого входа; ключи, значения и их исходный порядок сохранены. |
| Отказ и диагностика | Float-результат компаратора приводится к int, дробь меньше 1 превратится в 0. Неподходящие типы входных элементов и ошибки callback могут привести к исключению. Не изменяйте сравниваемые данные из callback. |
Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно. abs возвращает модуль числа: -3 и 3 дают одинаковое значение 3. strcasecmp во втором callback сравнивает ключи без учёта ASCII-регистра.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения.
- Кандидаты -3, 8, 3
- Сравнить модули со значением 3 и ключи
- Сохранить выбранные исходные пары, а не модули
<?php
$a = ["A" => -3, "B" => 8, "C" => 3];
$b = ["a" => 3];
$compare = function ($a, $b) { return abs($a) <=> abs($b); };
echo json_encode(array_uintersect_uassoc($a, $b, $compare, "strcasecmp")), "\n";
Ожидаемый результат
{"A":-3}
Равенство выражено возвратом 0. Модуль нужен только для сравнения, исходные числа не заменяются.
Первый опыт уже показал три исхода компаратора: меньше, равно, больше. Теперь параметрами будут записи-массивы. Форма каждой записи проверена заранее; нельзя предполагать, что left всегда из local, а right всегда из remote.
<?php
$local = ['SKU-A' => ['revision' => 2, 'label' => 'Карточка A'], 'SKU-B' => ['revision' => 3, 'label' => 'Карточка B']];
$remote = ['sku-a' => ['revision' => 2, 'label' => 'Другое название A'], 'sku-b' => ['revision' => 1, 'label' => 'Старое название B']];
$compareRevision = function ($left, $right) {
return $left["revision"] <=> $right["revision"];
};
$selected = array_uintersect_uassoc($local, $remote, $compareRevision, "strcasecmp");
foreach ($selected as $sku => $record) {
echo $sku, ": ", $record["label"], ", версия ", $record["revision"], "\n";
}
Ожидаемый результат
SKU-A: Карточка A, версия 2
Callback получает две целые записи, читает revision и возвращает знак сравнения. Для версий 2/2 это 0, для 3/1 — 1; алгоритм может дать их в обратном порядке или из одного входа. Дополнительно проверяются ключи вторым callback strcasecmp; сначала передан callback значений, потом ключей. Для sku-a совпадают ключ и версия; для sku-b версия отличается. Return всей операции — выбранные исходные записи local, поэтому выводится его label, а не удалённый. Поле label намеренно не входит в критерий: равная версия здесь не доказывает побайтовое равенство всей карточки.
Нюансы и выбор. Внутри сравнения массивы могут предварительно сортироваться, поэтому нельзя предполагать: $a всегда из local, $b всегда из remote. Нужен согласованный полный порядок (транзитивность, противоположные знаки при обмене аргументов), не функция «похож/не похож». Обход одноуровневый; callback сам выбирает поля вложенных значений. Для больших наборов с точным уникальным ID явный индекс нередко проще повторных сравнений.
Сравните: array_intersect, array_intersect_assoc, array_uintersect, array_uintersect_assoc. Выбрать операцию по задаче.
Реальная причина ошибки из вопроса о пропавших элементах: callback отдавал только 0/1 и не задавал согласованного порядка двух аргументов. Для отбора по одному признаку нужен array_filter; компаратор здесь обязан сравнить оба входа. Ответы обсуждения не служат нормативным правилом; договор проверен по PHP Manual.
sortУпорядочить значения по возрастанию, заменив все ключи индексами 0, 1….
PHP 4+ · standard
sort(array &$array, int $flags = SORT_REGULAR): trueУпорядочить значения по возрастанию, заменив все ключи индексами 0, 1….
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив; удаляются и строковые, и числовые старые ключи. |
| flags | SORT_REGULAR — обычные правила PHP; SORT_NUMERIC — числовые; SORT_STRING — строковые; SORT_LOCALE_STRING — строки в текущей locale; SORT_NATURAL — естественный порядок числовых частей строк. SORT_FLAG_CASE добавляют через | только к SORT_STRING/SORT_NATURAL для нечувствительности к ASCII-регистру (с PHP 8.2 только ASCII). |
| Возврат | true; тип объявлен как true с PHP 8.2, ранее bool. Сам результат сортировки находится в первом аргументе. |
| Отказ и диагностика | Неподходящий тип array — TypeError. Преобразование значений, несовместимых с режимом, может вызвать диагностику. SORT_REGULAR на смешанных типах часто не соответствует предметному правилу. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Исходные цены A=300, B=100, C=200.
- Сравнить цены по возрастанию.
- Прочитать изменённый prices с новыми позициями 0/1/2.
<?php
$prices = ['A' => 300, 'B' => 100, 'C' => 200];
$status = sort($prices, SORT_NUMERIC);
if ($status) { echo "Цены упорядочены\n"; }
foreach ($prices as $key => $price) { echo "Позиция ", $key, ": ", $price, " коп.\n"; }
Ожидаемый результат
Цены упорядочены
Позиция 0: 100 коп.
Позиция 1: 200 коп.
Позиция 2: 300 коп.
Сравниваются значения 300/100/200, а не подписи A/B/C. SORT_NUMERIC выбирает числовое сравнение. Все старые ключи A/B/C удалены и заменены позициями 0/1/2. Получен ряд цен; для каталога, которому нужны артикулы, выберите asort. Status получает true. Присвоить status переменной prices означало бы потерять сами отсортированные значения.
<?php
$files = ["ten" => "part10", "two" => "part2", "one" => "Part1"];
sort($files, SORT_NATURAL | SORT_FLAG_CASE);
echo json_encode($files), "\n";
Ожидаемый результат
["Part1","part2","part10"]
Часть 2 сравнивается как число и идёт перед частью 10 при возрастании. Флаг CASE убирает различие ASCII-регистра, а не меняет сами строки.
Нюансы и выбор. Для русских названий и языковых правил нужна подходящая locale/Collator, а не обещание универсального «алфавита». Не полагайтесь на конкретный алгоритм, число сравнений или скорость на любом входе. До сортировки нормализуйте сравниваемый тип; чтение БД уже в нужном порядке может быть выгоднее сортировки огромного PHP-массива.
Сравните: asort, ksort, usort, array_multisort. Выбрать операцию по задаче.
rsortУпорядочить значения по убыванию, заменив все ключи индексами 0, 1….
PHP 4+ · standard
rsort(array &$array, int $flags = SORT_REGULAR): trueУпорядочить значения по убыванию, заменив все ключи индексами 0, 1….
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив; удаляются и строковые, и числовые старые ключи. |
| flags | SORT_REGULAR — обычные правила PHP; SORT_NUMERIC — числовые; SORT_STRING — строковые; SORT_LOCALE_STRING — строки в текущей locale; SORT_NATURAL — естественный порядок числовых частей строк. SORT_FLAG_CASE добавляют через | только к SORT_STRING/SORT_NATURAL для нечувствительности к ASCII-регистру (с PHP 8.2 только ASCII). |
| Возврат | true; тип объявлен как true с PHP 8.2, ранее bool. Сам результат сортировки находится в первом аргументе. |
| Отказ и диагностика | Неподходящий тип array — TypeError. Преобразование значений, несовместимых с режимом, может вызвать диагностику. SORT_REGULAR на смешанных типах часто не соответствует предметному правилу. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Исходные цены A=300, B=100, C=200.
- Сравнить цены по убыванию.
- Прочитать изменённый prices с новыми позициями 0/1/2.
<?php
$prices = ['A' => 300, 'B' => 100, 'C' => 200];
$status = rsort($prices, SORT_NUMERIC);
if ($status) { echo "Цены упорядочены\n"; }
foreach ($prices as $key => $price) { echo "Позиция ", $key, ": ", $price, " коп.\n"; }
Ожидаемый результат
Цены упорядочены
Позиция 0: 300 коп.
Позиция 1: 200 коп.
Позиция 2: 100 коп.
Сравниваются значения 300/100/200, а не подписи A/B/C. SORT_NUMERIC выбирает числовое сравнение. Все старые ключи A/B/C удалены и заменены позициями 0/1/2. Получен ряд цен; для каталога, которому нужны артикулы, выберите arsort. Status получает true. Присвоить status переменной prices означало бы потерять сами отсортированные значения.
<?php
$files = ["ten" => "part10", "two" => "part2", "one" => "Part1"];
rsort($files, SORT_NATURAL | SORT_FLAG_CASE);
echo json_encode($files), "\n";
Ожидаемый результат
["part10","part2","Part1"]
Часть 2 сравнивается как число и идёт перед частью 10 при возрастании. Флаг CASE убирает различие ASCII-регистра, а не меняет сами строки.
Нюансы и выбор. Для русских названий и языковых правил нужна подходящая locale/Collator, а не обещание универсального «алфавита». Не полагайтесь на конкретный алгоритм, число сравнений или скорость на любом входе. До сортировки нормализуйте сравниваемый тип; чтение БД уже в нужном порядке может быть выгоднее сортировки огромного PHP-массива.
Сравните: sort, asort, ksort, usort, array_multisort. Выбрать операцию по задаче.
asortУпорядочить значения по возрастанию, сохранив связь ключей и значений.
PHP 4+ · standard
asort(array &$array, int $flags = SORT_REGULAR): trueУпорядочить значения по возрастанию, сохранив связь ключей и значений.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив; ключи не теряются. |
| flags | SORT_REGULAR — обычные правила PHP; SORT_NUMERIC — числовые; SORT_STRING — строковые; SORT_LOCALE_STRING — строки в текущей locale; SORT_NATURAL — естественный порядок числовых частей строк. SORT_FLAG_CASE добавляют через | только к SORT_STRING/SORT_NATURAL для нечувствительности к ASCII-регистру (с PHP 8.2 только ASCII). |
| Возврат | true; тип объявлен как true с PHP 8.2, ранее bool. Сам результат сортировки находится в первом аргументе. |
| Отказ и диагностика | Неподходящий тип array — TypeError. Преобразование значений, несовместимых с режимом, может вызвать диагностику. SORT_REGULAR на смешанных типах часто не соответствует предметному правилу. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Исходные цены A=300, B=100, C=200.
- Сравнить цены по возрастанию.
- Прочитать изменённый prices с артикулами.
<?php
$prices = ['A' => 300, 'B' => 100, 'C' => 200];
$status = asort($prices, SORT_NUMERIC);
if ($status) { echo "Цены упорядочены\n"; }
foreach ($prices as $key => $price) { echo "Артикул ", $key, ": ", $price, " коп.\n"; }
Ожидаемый результат
Цены упорядочены
Артикул B: 100 коп.
Артикул C: 200 коп.
Артикул A: 300 коп.
Сравниваются значения 300/100/200, а не подписи A/B/C. SORT_NUMERIC выбирает числовое сравнение. Связь каждого артикула с ценой сохранена, поэтому из результата можно строить список товаров. Status получает true. Присвоить status переменной prices означало бы потерять сами отсортированные значения.
<?php
$files = ["ten" => "part10", "two" => "part2", "one" => "Part1"];
asort($files, SORT_NATURAL | SORT_FLAG_CASE);
echo json_encode($files), "\n";
Ожидаемый результат
{"one":"Part1","two":"part2","ten":"part10"}
Часть 2 сравнивается как число и идёт перед частью 10 при возрастании. Флаг CASE убирает различие ASCII-регистра, а не меняет сами строки.
Нюансы и выбор. Для русских названий и языковых правил нужна подходящая locale/Collator, а не обещание универсального «алфавита». Не полагайтесь на конкретный алгоритм, число сравнений или скорость на любом входе. До сортировки нормализуйте сравниваемый тип; чтение БД уже в нужном порядке может быть выгоднее сортировки огромного PHP-массива.
Сравните: sort, ksort, usort, array_multisort. Выбрать операцию по задаче.
arsortУпорядочить значения по убыванию, сохранив связь ключей и значений.
PHP 4+ · standard
arsort(array &$array, int $flags = SORT_REGULAR): trueУпорядочить значения по убыванию, сохранив связь ключей и значений.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив; ключи не теряются. |
| flags | SORT_REGULAR — обычные правила PHP; SORT_NUMERIC — числовые; SORT_STRING — строковые; SORT_LOCALE_STRING — строки в текущей locale; SORT_NATURAL — естественный порядок числовых частей строк. SORT_FLAG_CASE добавляют через | только к SORT_STRING/SORT_NATURAL для нечувствительности к ASCII-регистру (с PHP 8.2 только ASCII). |
| Возврат | true; тип объявлен как true с PHP 8.2, ранее bool. Сам результат сортировки находится в первом аргументе. |
| Отказ и диагностика | Неподходящий тип array — TypeError. Преобразование значений, несовместимых с режимом, может вызвать диагностику. SORT_REGULAR на смешанных типах часто не соответствует предметному правилу. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Исходные цены A=300, B=100, C=200.
- Сравнить цены по убыванию.
- Прочитать изменённый prices с артикулами.
<?php
$prices = ['A' => 300, 'B' => 100, 'C' => 200];
$status = arsort($prices, SORT_NUMERIC);
if ($status) { echo "Цены упорядочены\n"; }
foreach ($prices as $key => $price) { echo "Артикул ", $key, ": ", $price, " коп.\n"; }
Ожидаемый результат
Цены упорядочены
Артикул A: 300 коп.
Артикул C: 200 коп.
Артикул B: 100 коп.
Сравниваются значения 300/100/200, а не подписи A/B/C. SORT_NUMERIC выбирает числовое сравнение. Связь каждого артикула с ценой сохранена, поэтому из результата можно строить список товаров. Status получает true. Присвоить status переменной prices означало бы потерять сами отсортированные значения.
<?php
$files = ["ten" => "part10", "two" => "part2", "one" => "Part1"];
arsort($files, SORT_NATURAL | SORT_FLAG_CASE);
echo json_encode($files), "\n";
Ожидаемый результат
{"ten":"part10","two":"part2","one":"Part1"}
Часть 2 сравнивается как число и идёт перед частью 10 при возрастании. Флаг CASE убирает различие ASCII-регистра, а не меняет сами строки.
Нюансы и выбор. Для русских названий и языковых правил нужна подходящая locale/Collator, а не обещание универсального «алфавита». Не полагайтесь на конкретный алгоритм, число сравнений или скорость на любом входе. До сортировки нормализуйте сравниваемый тип; чтение БД уже в нужном порядке может быть выгоднее сортировки огромного PHP-массива.
Сравните: sort, asort, ksort, usort, array_multisort. Выбрать операцию по задаче.
krsortУпорядочить ключи по убыванию, сохранив связь ключей и значений.
PHP 4+ · standard
krsort(array &$array, int $flags = SORT_REGULAR): trueУпорядочить ключи по убыванию, сохранив связь ключей и значений.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив; ключи не теряются. |
| flags | SORT_REGULAR — обычные правила PHP; SORT_NUMERIC — числовые; SORT_STRING — строковые; SORT_LOCALE_STRING — строки в текущей locale; SORT_NATURAL — естественный порядок числовых частей строк. SORT_FLAG_CASE добавляют через | только к SORT_STRING/SORT_NATURAL для нечувствительности к ASCII-регистру (с PHP 8.2 только ASCII). |
| Возврат | true; тип объявлен как true с PHP 8.2, ранее bool. Сам результат сортировки находится в первом аргументе. |
| Отказ и диагностика | Неподходящий тип array — TypeError. Преобразование значений, несовместимых с режимом, может вызвать диагностику. SORT_REGULAR на смешанных типах часто не соответствует предметному правилу. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится. В PHP 8.2 сравнение числовых строковых ключей SORT_REGULAR приведено к стандартным правилам PHP 8.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Исходный порядок ID 30,10,20.
- Сравнить только ключи по убыванию.
- Пройти изменённый invoices и показать накладные по ID.
<?php
$invoices = [30 => 'накладная C', 10 => 'накладная A', 20 => 'накладная B'];
$status = krsort($invoices, SORT_NUMERIC);
if ($status) { echo "Накладные упорядочены\n"; }
foreach ($invoices as $id => $title) { echo "ID ", $id, ": ", $title, "\n"; }
Ожидаемый результат
Накладные упорядочены
ID 30: накладная C
ID 20: накладная B
ID 10: накладная A
Сравниваются числовые ключи 30/10/20; текст накладной в сравнении не участвует. SORT_NUMERIC явно выбирает числовой порядок. Значение перемещается вместе со своим ID. Возврат status — true; результат сортировки находится в изменившемся invoices и сразу используется для отчёта.
<?php
$files = ["part10" => "ten", "part2" => "two", "Part1" => "one"];
krsort($files, SORT_NATURAL | SORT_FLAG_CASE);
echo json_encode($files), "\n";
Ожидаемый результат
{"part10":"ten","part2":"two","Part1":"one"}
Часть 2 сравнивается как число и идёт перед частью 10 при возрастании. Флаг CASE убирает различие ASCII-регистра, а не меняет сами строки.
Нюансы и выбор. Для русских названий и языковых правил нужна подходящая locale/Collator, а не обещание универсального «алфавита». Не полагайтесь на конкретный алгоритм, число сравнений или скорость на любом входе. До сортировки нормализуйте сравниваемый тип; чтение БД уже в нужном порядке может быть выгоднее сортировки огромного PHP-массива.
Сравните: sort, asort, ksort, usort, array_multisort. Выбрать операцию по задаче.
natsortОтсортировать числовые части строк естественным порядком, учитывая регистр.
PHP 4+ · standard
natsort(array &$array): trueОтсортировать числовые части строк естественным порядком, учитывая регистр.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемый массив строк. Ключи и их связь со значениями сохраняются. Дополнительных flags нет. |
| Возврат | true (тип уточнён в PHP 8.2); значения переставлены в исходном массиве. |
| Отказ и диагностика | Неверный тип array — TypeError; неоднородные и непреобразуемые к строке значения не являются подходящим входом. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Значения в порядке part10,part2,part1.
- Числовые части сравниваются как 10,2,1.
- Вывести part1,part2,part10 вместе с сохранёнными ID.
<?php
$pages = ['ten' => 'part10', 'two' => 'part2', 'one' => 'part1'];
natsort($pages);
foreach ($pages as $id => $file) {
echo 'Раздел ', $id, ': ', $file, ".txt\n";
}
Ожидаемый результат
Раздел one: part1.txt
Раздел two: part2.txt
Раздел ten: part10.txt
Функция сравнивает числовые части строк: 1,2,10. Возврат — статус true, поэтому его не присваивают pages. Изменённый массив сохраняет связь one/two/ten с соответствующими именами файлов; следующий foreach готовит порядок списка инструкции. Файлы здесь не читаются и не создаются. Для одних и тех же строчных имён обе natural-функции дают одинаковый порядок; следующий опыт показывает, что меняется при разном регистре.
<?php
$sensitive = ['x2', 'X10', 'x1'];
$insensitive = $sensitive;
natsort($sensitive);
natcasesort($insensitive);
echo json_encode(array_values($sensitive)), "
";
echo json_encode(array_values($insensitive)), "
";
Ожидаемый результат
["X10","x1","x2"]
["x1","x2","X10"]
Два режима дают разный результат на одном списке; выберите правило до сортировки. array_values здесь только делает вывод списком.
Нюансы и выбор. «Естественный» не означает понимание версий, дат, дробей или всех языков. Ведущие нули и формат чисел важны; для SemVer нужен его собственный договор сравнения. Для обратного результата можно array_reverse(..., true), если хотите сохранить ключи; это также перевернёт порядок равных элементов.
Сравните: natcasesort, asort, array_reverse. Выбрать операцию по задаче.
natcasesortОтсортировать числовые части строк естественным порядком без учёта ASCII-регистра.
PHP 4+ · standard
natcasesort(array &$array): trueОтсортировать числовые части строк естественным порядком без учёта ASCII-регистра.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемый массив строк. Ключи и их связь со значениями сохраняются. Дополнительных flags нет. |
| Возврат | true (тип уточнён в PHP 8.2); значения переставлены в исходном массиве. |
| Отказ и диагностика | Неверный тип array — TypeError; неоднородные и непреобразуемые к строке значения не являются подходящим входом. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Значения в порядке part10,part2,part1.
- Числовые части сравниваются как 10,2,1.
- Вывести part1,part2,part10 вместе с сохранёнными ID.
<?php
$pages = ['ten' => 'part10', 'two' => 'part2', 'one' => 'part1'];
natcasesort($pages);
foreach ($pages as $id => $file) {
echo 'Раздел ', $id, ': ', $file, ".txt\n";
}
Ожидаемый результат
Раздел one: part1.txt
Раздел two: part2.txt
Раздел ten: part10.txt
Функция сравнивает числовые части строк: 1,2,10. Возврат — статус true, поэтому его не присваивают pages. Изменённый массив сохраняет связь one/two/ten с соответствующими именами файлов; следующий foreach готовит порядок списка инструкции. Файлы здесь не читаются и не создаются. Для одних и тех же строчных имён обе natural-функции дают одинаковый порядок; следующий опыт показывает, что меняется при разном регистре.
<?php
$sensitive = ['x2', 'X10', 'x1'];
$insensitive = $sensitive;
natsort($sensitive);
natcasesort($insensitive);
echo json_encode(array_values($sensitive)), "
";
echo json_encode(array_values($insensitive)), "
";
Ожидаемый результат
["X10","x1","x2"]
["x1","x2","X10"]
Два режима дают разный результат на одном списке; выберите правило до сортировки. array_values здесь только делает вывод списком.
Нюансы и выбор. «Естественный» не означает понимание версий, дат, дробей или всех языков. Ведущие нули и формат чисел важны; для SemVer нужен его собственный договор сравнения. Для обратного результата можно array_reverse(..., true), если хотите сохранить ключи; это также перевернёт порядок равных элементов.
Сравните: natsort, asort, array_reverse. Выбрать операцию по задаче.
uasortЗадать своё правило порядка значений, сохранив исходные ключи.
PHP 4+ · standard
uasort(array &$array, callable $callback): trueЗадать своё правило порядка значений, сохранив исходные ключи.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемый массив; связь ключ–значение сохранена. |
| callback | callback(a,b): int сравнивает значения. Допустим любой отрицательный/нулевой/положительный int, не только -1/0/1. |
| Возврат | true; тип уточнён с bool в PHP 8.2. Массив находится в первом аргументе. |
| Отказ и диагностика | С PHP 8 параметры callback по ссылке вызывают E_WARNING. Float приводится к int, например 0.6 превращается в 0. Булевый компаратор не задаёт три исхода; возврат bool устарел с PHP 8. Ошибки callback распространяются наружу. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится. Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения; оператор <=> и условный выбор.
- Есть массы 2.7,2.1,2.4.
- Callback сравнивает пару масс и возвращает знак целым числом.
- В weights получен порядок 2.1,2.4,2.7; его показывает foreach.
<?php
$weights = ['large' => 2.7, 'small' => 2.1, 'middle' => 2.4];
uasort($weights, function ($left, $right) {
return $left <=> $right;
});
foreach ($weights as $key => $weight) {
echo 'Упаковка ', $key, ': ', $weight, " кг\n";
}
Ожидаемый результат
Упаковка small: 2.1 кг
Упаковка middle: 2.4 кг
Упаковка large: 2.7 кг
Первый аргумент — изменяемый массив, второй — функция как значение. Алгоритм сам многократно передаёт в left/right две массы; конкретный порядок вызовов не обещан. Оператор <=> возвращает int: например, для 2.1 и 2.7 это -1, для обратной пары 1, для одинаковых значений 0. Этот return поступает в алгоритм сортировки, а не в weights. После завершения внешний foreach читает массы в новом порядке. Исходные имена упаковок сохранены. Дробную разность left-right возвращать нельзя: приведение к int превратило бы 0.6 в 0.
<?php
$orders = ["c" => ["priority" => 2, "id" => 30], "a" => ["priority" => 1, "id" => 20], "b" => ["priority" => 1, "id" => 10]];
uasort($orders, function ($a, $b) {
$byPriority = $a["priority"] <=> $b["priority"];
return $byPriority !== 0 ? $byPriority : $a["id"] <=> $b["id"];
});
echo json_encode(array_column($orders, "id")), "\n";
echo json_encode(array_keys($orders)), "\n";
Ожидаемый результат
[10,20,30]
["b","a","c"]
Сначала сравниваем приоритет, при равенстве — ID. ?: выбирает один результат; <=> вычисляет целое сравнение даже для float.
Нюансы и выбор. Компаратор должен задавать согласованный порядок, а не решать «эти похожи»: нарушенная транзитивность делает результат ненадёжным. Не выполняйте внутри каждого сравнения сетевой запрос или дорогое преобразование; предварительно вычислите сортировочные поля. Два поля с равным критерием сохраняют исходный порядок в PHP 8, но порядок исходного ответа БД сам по себе может быть не определён без ORDER BY.
Сравните: usort, uksort, sort, array_multisort. Выбрать операцию по задаче.
uksortЗадать своё правило порядка ключей, сохранив исходные ключи.
PHP 4+ · standard
uksort(array &$array, callable $callback): trueЗадать своё правило порядка ключей, сохранив исходные ключи.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемый массив; связь ключ–значение сохранена. |
| callback | callback(a,b): int сравнивает ключи. Допустим любой отрицательный/нулевой/положительный int, не только -1/0/1. |
| Возврат | true; тип уточнён с bool в PHP 8.2. Массив находится в первом аргументе. |
| Отказ и диагностика | С PHP 8 параметры callback по ссылке вызывают E_WARNING. Float приводится к int, например 0.6 превращается в 0. Булевый компаратор не задаёт три исхода; возврат bool устарел с PHP 8. Ошибки callback распространяются наружу. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится. Компаратор — функция сравнения двух элементов. Она возвращает целое число: отрицательное — первый раньше, 0 — равны по выбранному признаку, положительное — первый позже. $a <=> $b даёт -1, 0 или 1. Это не проверка true/false; разность дробей нельзя возвращать вместо целого результата. function ($a, $b) { return ...; } передаёт правило операции, а не вызывает его немедленно.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
Для этого примера: передача функции как значения; оператор <=> и условный выбор.
- Части документа пришли footer,main,header.
- Таблица rank задаёт header=0,main=1,footer=2.
- Сравнить ранги ключей и вывести Заголовок,Текст,Подпись.
<?php
$sections = ['footer' => 'Подпись', 'main' => 'Текст', 'header' => 'Заголовок'];
$rank = ['header' => 0, 'main' => 1, 'footer' => 2];
uksort($sections, function ($left, $right) use ($rank) {
return $rank[$left] <=> $rank[$right];
});
foreach ($sections as $name => $text) {
echo $name, ': ', $text, "\n";
}
Ожидаемый результат
header: Заголовок
main: Текст
footer: Подпись
Uksort передаёт callback ключи header/main/footer, а не содержимое «Заголовок/Текст/Подпись». Use ($rank) сохраняет доступ к таблице порядка при создании callback. Например, сравнение header/footer получает 0<=>2 и возвращает -1, ставя header раньше. Значение переносится вместе с ключом. Все имена в этом примере присутствуют в rank; следующий опыт показывает запасное место для неизвестного имени.
<?php
$sections = ['footer' => 'F', 'main' => 'M', 'header' => 'H'];
$rank = ['header' => 0, 'main' => 1, 'footer' => 2];
uksort($sections, function ($a, $b) use ($rank) {
return ($rank[$a] ?? 99) <=> ($rank[$b] ?? 99);
});
echo implode(',', array_keys($sections)), "
";
Ожидаемый результат
header,main,footer
use ($rank) захватывает таблицу при создании callback; ?? задаёт место неизвестного ключа. Сортируется имя раздела, а не его содержимое.
Нюансы и выбор. Компаратор должен задавать согласованный порядок, а не решать «эти похожи»: нарушенная транзитивность делает результат ненадёжным. Не выполняйте внутри каждого сравнения сетевой запрос или дорогое преобразование; предварительно вычислите сортировочные поля. Здесь значения callback не передаются; захватывайте отдельную проверенную таблицу через use, если порядок ключей зависит от неё.
Сравните: usort, uasort, sort, array_multisort. Выбрать операцию по задаче.
array_multisortСинхронно переставить несколько колонок, применяя следующие как дополнительные критерии.
PHP 4+ · standard
array_multisort(array &$array1, mixed $array1_sort_order = SORT_ASC, mixed $array1_sort_flags = SORT_REGULAR, mixed ...$rest): trueСинхронно переставить несколько колонок, применяя следующие как дополнительные критерии.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array1 | Первая изменяемая колонка. |
| array1_sort_order | SORT_ASC или SORT_DESC для предыдущей колонки; по умолчанию ASC. Можно поменять местами с flags либо опустить. |
| array1_sort_flags | SORT_REGULAR — обычные правила PHP; SORT_NUMERIC — числовые; SORT_STRING — строковые; SORT_LOCALE_STRING — строки в текущей locale; SORT_NATURAL — естественный порядок числовых частей строк. SORT_FLAG_CASE добавляют через | только к SORT_STRING/SORT_NATURAL для нечувствительности к ASCII-регистру (с PHP 8.2 только ASCII). По умолчанию REGULAR; можно поменять местами с order либо опустить. |
| rest | Следующие изменяемые массивы той же длины, у каждого свои необязательные order/flags. Следующая колонка сравнивается только при равенстве всех предыдущих; это лексикографический порядок. |
| Возврат | true (точный тип с PHP 8.5, ранее bool). Все переданные массивы переставлены; строковые ключи сохранены, числовые перенумерованы. |
| Отказ и диагностика | Разная длина массивов — ValueError; неподходящие аргументы/флаги — TypeError или ValueError в зависимости от нарушения. Для каждого передаваемого массива нужна переменная. |
Все равные по правилу сравнения элементы сохраняют взаимный порядок с PHP 8.0; раньше он не гарантировался. Указатель массива сбрасывается на первый элемент. Массив меняется на месте: true — статус, не отсортированные данные. В сигнатуре & означает передачу изменяемой переменной; в вызове знак & не ставится. Колонки соединяются по позиции. Они должны описывать одни и те же строки до сортировки, а не просто иметь одинаковую длину.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Три пары: 20↔90,10↔90,30↔70.
- Баллы по убыванию; при равенстве ID по возрастанию.
- Прочитать обе изменённые колонки по общей позиции.
<?php
$scores = [90, 90, 70];
$ids = [20, 10, 30];
array_multisort($scores, SORT_DESC, SORT_NUMERIC, $ids, SORT_ASC, SORT_NUMERIC);
foreach ($ids as $position => $id) {
echo 'Место ', $position + 1, ': ID ', $id, ' — ', $scores[$position], ' баллов', "\n";
}
Ожидаемый результат
Место 1: ID 10 — 90 баллов
Место 2: ID 20 — 90 баллов
Место 3: ID 30 — 70 баллов
До вызова позиции связывают 20↔90, 10↔90, 30↔70. После scores идут её флаги: DESC убывание и NUMERIC числовое сравнение. Затем ids и её ASC/NUMERIC. ID сравнивается только при одинаковых баллах, поэтому 10 стоит раньше 20. Обе переменные переставлены синхронно; foreach берёт ID и баллы одной новой позиции. Возврат самой функции — true, не таблица рейтинга.
<?php
$rows = [['id' => 20, 'price' => 100], ['id' => 10, 'price' => 100], ['id' => 30, 'price' => 50]];
$prices = array_column($rows, 'price');
$positions = array_keys($rows);
array_multisort($prices, SORT_ASC, SORT_NUMERIC, $positions, SORT_ASC, SORT_NUMERIC, $rows);
echo json_encode(array_column($rows, 'id')), "
";
Ожидаемый результат
[30,20,10]
Если передать только prices и rows, сами строки станут следующим критерием. Явные исходные позиции перед rows исключают такой скрытый порядок.
<?php
$prices = [100, 200];
$ids = [10];
try { array_multisort($prices, $ids); }
catch (ValueError $error) { echo "Разная длина колонок
"; }
Ожидаемый результат
Разная длина колонок
Проверка count до сортировки позволяет объяснить ошибку импорта на своей границе. В отличие от array_map отсутствующие позиции не дополняются null.
Нюансы и выбор. Для небольшого массива записей usort с явным callback может быть понятнее параллельных колонок. Стабильность PHP 8 относится к равенству по всем переданным критериям, а не только первому. Не теряйте числовые ID, используя их как ключи сортируемого массива без отдельного поля.
Сравните: usort, uasort, array_column, array_map. Выбрать операцию по задаче.
currentпрочитать текущее значение без перемещения указателя.
PHP 4+ · standard
current(array|object $array): mixedпрочитать текущее значение без перемещения указателя.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив с текущей позицией. Историческая поддержка объектов устарела; в новом коде передавайте массив. |
| Возврат | Значение элемента; false для пустого массива или позиции за его пределами. Сам элемент тоже может содержать false. |
| Отказ и диагностика | Неверный тип — TypeError; объект вызывает E_DEPRECATED с PHP 8.1. Строгое сравнение с false отличает 0/"" от false, но не отличает элемент false от конца: проверяйте key(...) !== null. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка.
- Позиция стоит на address→Проверить адрес.
- Два чтения дают одинаковую подпись.
- Next перемещает позицию к pack→Упаковать.
<?php
$steps = ['address' => 'Проверить адрес', 'pack' => 'Упаковать'];
$caption = current($steps);
echo 'Сейчас: ', $caption, "\n";
echo 'Повторное чтение: ', current($steps), "\n";
next($steps);
echo 'После перехода: ', current($steps), "\n";
Ожидаемый результат
Сейчас: Проверить адрес
Повторное чтение: Проверить адрес
После перехода: Упаковать
У нового steps внутренняя позиция стоит на address. Возврат current — строка текущего значения; присваивание caption сохраняет её для подписи. Повторное чтение возвращает ту же строку. Только next меняет позицию на pack. Это чтение плана: вывод названия не означает, что адрес проверен или упаковка выполнена. Pos — полное другое имя current с тем же договором.
<?php
$states = ["ready" => false, "count" => 0];
while (key($states) !== null) {
echo key($states), "=";
var_dump(current($states));
next($states);
}
var_dump(current($states));
Ожидаемый результат
ready=bool(false)
count=int(0)
bool(false)
key вернул имя ready, поэтому false был настоящими данными. После последнего next ключ становится null, а значение-чтение — false.
Нюансы и выбор. Вызовы этих функций на объектах устарели с PHP 8.1. Для свойств объекта сначала явно выберите представление массива, например get_mangled_object_vars; для Iterator используйте его методы. С PHP 7.4 SPL-объекты здесь рассматриваются как объекты без свойств, а не как команда вызвать одноимённый метод Iterator. Не передавайте результат current в if как единственный признак наличия элемента. Для первого значения без влияния чужих перемещений есть array_first в PHP 8.5+.
Сравните: pos, key, next, reset, array_first. Выбрать операцию по задаче.
posПсевдоним current: прочитать текущее значение без перемещения указателя.
PHP 4+ · standard
pos(array|object $array): mixedПсевдоним current: прочитать текущее значение без перемещения указателя.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив с текущей позицией. Историческая поддержка объектов устарела; в новом коде передавайте массив. |
| Возврат | Значение элемента; false для пустого массива или позиции за его пределами. Сам элемент тоже может содержать false. |
| Отказ и диагностика | Неверный тип — TypeError; объект вызывает E_DEPRECATED с PHP 8.1. Строгое сравнение с false отличает 0/"" от false, но не отличает элемент false от конца: проверяйте key(...) !== null. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка.
- Позиция стоит на address→Проверить адрес.
- Два чтения дают одинаковую подпись.
- Next перемещает позицию к pack→Упаковать.
<?php
$steps = ['address' => 'Проверить адрес', 'pack' => 'Упаковать'];
$caption = pos($steps);
echo 'Сейчас: ', $caption, "\n";
echo 'Повторное чтение: ', pos($steps), "\n";
next($steps);
echo 'После перехода: ', pos($steps), "\n";
Ожидаемый результат
Сейчас: Проверить адрес
Повторное чтение: Проверить адрес
После перехода: Упаковать
У нового steps внутренняя позиция стоит на address. Возврат pos — строка текущего значения; присваивание caption сохраняет её для подписи. Повторное чтение возвращает ту же строку. Только next меняет позицию на pack. Это чтение плана: вывод названия не означает, что адрес проверен или упаковка выполнена. Pos — полное другое имя current с тем же договором.
<?php
$states = ["ready" => false, "count" => 0];
while (key($states) !== null) {
echo key($states), "=";
var_dump(pos($states));
next($states);
}
var_dump(pos($states));
Ожидаемый результат
ready=bool(false)
count=int(0)
bool(false)
key вернул имя ready, поэтому false был настоящими данными. После последнего next ключ становится null, а значение-чтение — false.
Нюансы и выбор. Вызовы этих функций на объектах устарели с PHP 8.1. Для свойств объекта сначала явно выберите представление массива, например get_mangled_object_vars; для Iterator используйте его методы. С PHP 7.4 SPL-объекты здесь рассматриваются как объекты без свойств, а не как команда вызвать одноимённый метод Iterator. Не передавайте результат current в if как единственный признак наличия элемента. Для первого значения без влияния чужих перемещений есть array_first в PHP 8.5+.
Сравните: current, key, next, reset, array_first. Выбрать операцию по задаче.
keyПрочитать ключ в текущей позиции; null показывает отсутствие позиции.
PHP 4+ · standard
key(array|object $array): int|string|nullПрочитать ключ в текущей позиции; null показывает отсутствие позиции.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Массив с текущей позицией; объектный режим устарел с PHP 8.1. |
| Возврат | Ключ int/string, либо null для пустого массива или указателя вне элементов. Указатель не сдвигается. |
| Отказ и диагностика | Неверный тип — TypeError; объекты дают E_DEPRECATED с PHP 8.1. Ключ 0 или пустая строка — допустимый результат, не признак конца. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка.
- Текущий ключ 10 открывает Накладную A.
- После next ключ 50 открывает Накладную B.
- За краем key возвращает null; показать завершение.
<?php
$documents = [10 => 'Накладная A', 50 => 'Накладная B'];
$id = key($documents);
if ($id !== null) { echo 'Выбрано ID ', $id, ': ', $documents[$id], "\n"; }
next($documents);
$id = key($documents);
if ($id !== null) { echo 'Выбрано ID ', $id, ': ', $documents[$id], "\n"; }
next($documents);
if (key($documents) === null) { echo "Больше накладных нет\n"; }
Ожидаемый результат
Выбрано ID 10: Накладная A
Выбрано ID 50: Накладная B
Больше накладных нет
Key возвращает ключ текущей позиции, сначала 10. Он сохранён в id и использован в documents[id]; функция не возвращала весь документ. Next переходит к следующему элементу 50, а не к арифметическому ключу 11. После второго перехода позиции нет: key возвращает null. Строгая проверка сохраняет допустимый ключ 0. Чтение key само не двигает позицию.
<?php
$fields = ['' => 'empty-name', 0 => 'zero'];
while (key($fields) !== null) {
echo '[', key($fields), ']=', current($fields), "
";
next($fields);
}
Ожидаемый результат
[]=empty-name
[0]=zero
Условие if (key(...)) пропустило бы оба ключа; строгое сравнение решает именно проверку позиции.
Нюансы и выбор. Вызовы этих функций на объектах устарели с PHP 8.1. Для свойств объекта сначала явно выберите представление массива, например get_mangled_object_vars; для Iterator используйте его методы. С PHP 7.4 SPL-объекты здесь рассматриваются как объекты без свойств, а не как команда вызвать одноимённый метод Iterator. Это ключ внутреннего указателя, не переменная $key из отдельно выполняемого foreach. Для края без перемещения используйте array_key_first/last.
Сравните: current, next, array_key_first, array_key_last. Выбрать операцию по задаче.
nextПереместить внутренний указатель вперёд на один элемент и прочитать новое значение.
PHP 4+ · standard
next(array|object &$array): mixedПереместить внутренний указатель вперёд на один элемент и прочитать новое значение.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив: значения остаются, меняется позиция. Поэтому нельзя передавать временный литерал/результат выражения как by-reference аргумент. |
| Возврат | Значение новой позиции; false, если её нет. Для reset/end пустой массив даёт false; для next/prev — также выход за край. Элемент false остаётся неоднозначным без key. |
| Отказ и диагностика | Неподходящий тип — TypeError; объектный вызов устарел с PHP 8.1. Требуется реальная переменная для аргумента по ссылке. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка. Знак & в сигнатуре обозначает изменяемый аргумент, а не необходимость писать & в вызове.
- Документы имеют ключи 10,50,90.
- Переместить позицию к ID 50 и получить его название.
- Показать выбор, затем все три сохранённых документа.
<?php
$documents = [10 => 'Накладная A', 50 => 'Накладная B', 90 => 'Накладная C'];
$title = next($documents);
if (key($documents) !== null) {
echo "Текущий документ ID ", key($documents), ": ", $title, "\n";
}
echo "Все документы сохранены:\n";
foreach ($documents as $id => $item) { echo $id, ": ", $item, "\n"; }
Ожидаемый результат
Текущий документ ID 50: Накладная B
Все документы сохранены:
10: Накладная A
50: Накладная B
90: Накладная C
Позиция нового массива начинается с ID 10. next перемещает её к ID 50 и возвращает значение новой позиции в title. Key проверяет существование позиции и даёт ID для подписи. Дальнейший foreach показывает все три документа с исходными ключами: перемещение не удалило ни один. Его обход не начинается с текущего курсора. False от функции могло бы быть настоящим значением, поэтому признак наличия читается через key !== null.
<?php
$states = ["start" => 1, "present" => false];
next($states);
var_dump(current($states));
echo key($states) !== null ? "Элемент существует\n" : "Нет позиции\n";
$empty = [];
var_dump(next($empty));
Ожидаемый результат
bool(false)
Элемент существует
bool(false)
После перемещения нужно проверить key !== null. Сравнение значения с false само по себе не даёт ответа.
Нюансы и выбор. Вызовы этих функций на объектах устарели с PHP 8.1. Для свойств объекта сначала явно выберите представление массива, например get_mangled_object_vars; для Iterator используйте его методы. С PHP 7.4 SPL-объекты здесь рассматриваются как объекты без свойств, а не как команда вызвать одноимённый метод Iterator. Для обычного обхода foreach проще ручного управления позицией. Если массив меняется структурно в процессе, пересмотрите договор обхода.
Сравните: prev, reset, end, current, key. Выбрать операцию по задаче.
prevПереместить внутренний указатель назад на один элемент и прочитать новое значение.
PHP 4+ · standard
prev(array|object &$array): mixedПереместить внутренний указатель назад на один элемент и прочитать новое значение.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив: значения остаются, меняется позиция. Поэтому нельзя передавать временный литерал/результат выражения как by-reference аргумент. |
| Возврат | Значение новой позиции; false, если её нет. Для reset/end пустой массив даёт false; для next/prev — также выход за край. Элемент false остаётся неоднозначным без key. |
| Отказ и диагностика | Неподходящий тип — TypeError; объектный вызов устарел с PHP 8.1. Требуется реальная переменная для аргумента по ссылке. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка. Знак & в сигнатуре обозначает изменяемый аргумент, а не необходимость писать & в вызове.
- Документы имеют ключи 10,50,90.
- Переместить позицию к ID 50 и получить его название.
- Показать выбор, затем все три сохранённых документа.
<?php
$documents = [10 => 'Накладная A', 50 => 'Накладная B', 90 => 'Накладная C'];
end($documents);
$title = prev($documents);
if (key($documents) !== null) {
echo "Текущий документ ID ", key($documents), ": ", $title, "\n";
}
echo "Все документы сохранены:\n";
foreach ($documents as $id => $item) { echo $id, ": ", $item, "\n"; }
Ожидаемый результат
Текущий документ ID 50: Накладная B
Все документы сохранены:
10: Накладная A
50: Накладная B
90: Накладная C
Начальное end ставит позицию на ID 90. prev перемещает её к ID 50 и возвращает значение новой позиции в title. Key проверяет существование позиции и даёт ID для подписи. Дальнейший foreach показывает все три документа с исходными ключами: перемещение не удалило ни один. Его обход не начинается с текущего курсора. False от функции могло бы быть настоящим значением, поэтому признак наличия читается через key !== null.
<?php
$states = ["present" => false, "end" => 1];
end($states);
prev($states);
var_dump(current($states));
echo key($states) !== null ? "Элемент существует\n" : "Нет позиции\n";
$empty = [];
var_dump(prev($empty));
Ожидаемый результат
bool(false)
Элемент существует
bool(false)
После перемещения нужно проверить key !== null. Сравнение значения с false само по себе не даёт ответа.
Нюансы и выбор. Вызовы этих функций на объектах устарели с PHP 8.1. Для свойств объекта сначала явно выберите представление массива, например get_mangled_object_vars; для Iterator используйте его методы. С PHP 7.4 SPL-объекты здесь рассматриваются как объекты без свойств, а не как команда вызвать одноимённый метод Iterator. Для обычного обхода foreach проще ручного управления позицией. Если массив меняется структурно в процессе, пересмотрите договор обхода.
Сравните: next, reset, end, current, key. Выбрать операцию по задаче.
resetПереместить внутренний указатель на первый элемент и прочитать новое значение.
PHP 4+ · standard
reset(array|object &$array): mixedПереместить внутренний указатель на первый элемент и прочитать новое значение.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив: значения остаются, меняется позиция. Поэтому нельзя передавать временный литерал/результат выражения как by-reference аргумент. |
| Возврат | Значение новой позиции; false, если её нет. Для reset/end пустой массив даёт false; для next/prev — также выход за край. Элемент false остаётся неоднозначным без key. |
| Отказ и диагностика | Неподходящий тип — TypeError; объектный вызов устарел с PHP 8.1. Требуется реальная переменная для аргумента по ссылке. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка. Знак & в сигнатуре обозначает изменяемый аргумент, а не необходимость писать & в вызове.
- Документы имеют ключи 10,50,90.
- Переместить позицию к ID 10 и получить его название.
- Показать выбор, затем все три сохранённых документа.
<?php
$documents = [10 => 'Накладная A', 50 => 'Накладная B', 90 => 'Накладная C'];
end($documents);
$title = reset($documents);
if (key($documents) !== null) {
echo "Текущий документ ID ", key($documents), ": ", $title, "\n";
}
echo "Все документы сохранены:\n";
foreach ($documents as $id => $item) { echo $id, ": ", $item, "\n"; }
Ожидаемый результат
Текущий документ ID 10: Накладная A
Все документы сохранены:
10: Накладная A
50: Накладная B
90: Накладная C
Начальное end ставит позицию на ID 90. reset перемещает её к ID 10 и возвращает значение новой позиции в title. Key проверяет существование позиции и даёт ID для подписи. Дальнейший foreach показывает все три документа с исходными ключами: перемещение не удалило ни один. Его обход не начинается с текущего курсора. False от функции могло бы быть настоящим значением, поэтому признак наличия читается через key !== null.
<?php
$states = ["present" => false, "end" => 1];
end($states);
reset($states);
var_dump(current($states));
echo key($states) !== null ? "Элемент существует\n" : "Нет позиции\n";
$empty = [];
var_dump(reset($empty));
Ожидаемый результат
bool(false)
Элемент существует
bool(false)
После перемещения нужно проверить key !== null. Сравнение значения с false само по себе не даёт ответа.
Нюансы и выбор. Вызовы этих функций на объектах устарели с PHP 8.1. Для свойств объекта сначала явно выберите представление массива, например get_mangled_object_vars; для Iterator используйте его методы. С PHP 7.4 SPL-объекты здесь рассматриваются как объекты без свойств, а не как команда вызвать одноимённый метод Iterator. Для безопасного начала повторного обхода явно reset; не рассчитывайте, что копирование массива обязано переместить чужой указатель.
Сравните: next, prev, end, current, key. Выбрать операцию по задаче.
endПереместить внутренний указатель на последний элемент и прочитать новое значение.
PHP 4+ · standard
end(array|object &$array): mixedПереместить внутренний указатель на последний элемент и прочитать новое значение.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив: значения остаются, меняется позиция. Поэтому нельзя передавать временный литерал/результат выражения как by-reference аргумент. |
| Возврат | Значение новой позиции; false, если её нет. Для reset/end пустой массив даёт false; для next/prev — также выход за край. Элемент false остаётся неоднозначным без key. |
| Отказ и диагностика | Неподходящий тип — TypeError; объектный вызов устарел с PHP 8.1. Требуется реальная переменная для аргумента по ссылке. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка. Знак & в сигнатуре обозначает изменяемый аргумент, а не необходимость писать & в вызове.
- Документы имеют ключи 10,50,90.
- Переместить позицию к ID 90 и получить его название.
- Показать выбор, затем все три сохранённых документа.
<?php
$documents = [10 => 'Накладная A', 50 => 'Накладная B', 90 => 'Накладная C'];
$title = end($documents);
if (key($documents) !== null) {
echo "Текущий документ ID ", key($documents), ": ", $title, "\n";
}
echo "Все документы сохранены:\n";
foreach ($documents as $id => $item) { echo $id, ": ", $item, "\n"; }
Ожидаемый результат
Текущий документ ID 90: Накладная C
Все документы сохранены:
10: Накладная A
50: Накладная B
90: Накладная C
Позиция нового массива начинается с ID 10. end перемещает её к ID 90 и возвращает значение новой позиции в title. Key проверяет существование позиции и даёт ID для подписи. Дальнейший foreach показывает все три документа с исходными ключами: перемещение не удалило ни один. Его обход не начинается с текущего курсора. False от функции могло бы быть настоящим значением, поэтому признак наличия читается через key !== null.
<?php
$states = ["start" => 1, "present" => false];
end($states);
var_dump(current($states));
echo key($states) !== null ? "Элемент существует\n" : "Нет позиции\n";
$empty = [];
var_dump(end($empty));
Ожидаемый результат
bool(false)
Элемент существует
bool(false)
После перемещения нужно проверить key !== null. Сравнение значения с false само по себе не даёт ответа.
Нюансы и выбор. Вызовы этих функций на объектах устарели с PHP 8.1. Для свойств объекта сначала явно выберите представление массива, например get_mangled_object_vars; для Iterator используйте его методы. С PHP 7.4 SPL-объекты здесь рассматриваются как объекты без свойств, а не как команда вызвать одноимённый метод Iterator. Если нужно только крайнее значение без изменения позиции, используйте array_first/last в PHP 8.5+ либо чтение по array_key_first/last в прежних версиях.
Сравните: next, prev, reset, current, key. Выбрать операцию по задаче.
eachИсторическая функция чтения пары и перемещения указателя: удалена из PHP 8; нужна для понимания и миграции старого кода.
PHP 4–7; deprecated 7.2, removed 8.0 · standard
Исторически each(array|object &$array): array|false; в PHP 8 отсутствуетИсторическая функция чтения пары и перемещения указателя: удалена из PHP 8; нужна для понимания и миграции старого кода.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Исторически изменяла внутренний указатель переданного массива, переходя к следующему элементу после чтения текущего. |
| Возврат | В PHP 7 возвращала четыре поля: 0 и key содержали ключ; 1 и value — значение. За пределами массива false. Для повторного обхода требовался reset. |
| Отказ и диагностика | Deprecated с PHP 7.2, удалена в PHP 8.0. Вызов в PHP 8 приводит к Error: Call to undefined function each(). Историческая работа с объектами могла давать неожиданные результаты. |
Внутренний указатель — сохранённая позиция внутри массива, а не его числовой ключ. Изначально он указывает на первый добавленный элемент. current/pos и key читают позицию, next/prev/reset/end её меняют. foreach имеет собственный механизм обхода и обычно понятнее для обычного списка. Ниже сначала виден старый шаблон, затем два самостоятельных способа переноса. Исторические предупреждения о копировании массива относятся к старому коду each, не являются обещанием современных правил копирования.
- Старый each читал текущую пару
- Сам перемещал указатель дальше
- Миграция выбирает foreach либо явный курсор
<?php
$items = ['x' => 4, 'y' => 9];
while (list($key, $value) = each($items)) {
echo $key, '=', $value, "
";
}
Негативный фрагмент для распознавания: PHP 8 выдаст Error об отсутствующей each. list распределял два позиционных поля исторического ответа.
<?php
$items = ['x' => 4, 'y' => 9];
foreach ($items as $key => $value) { echo $key, '=', $value, "
"; }
Ожидаемый результат
x=4
y=9
Если задача — просто пройти все элементы, foreach выражает её прямо и допускает false в значениях.
<?php
$items = ['x' => 4, 'y' => 9, 'z' => 12];
next($items);
while (key($items) !== null) {
$key = key($items);
$value = current($items);
next($items);
echo $key, '=', $value, "
";
}
Ожидаемый результат
y=9
z=12
Простая замена на полный foreach изменила бы смысл: он начал бы с x. Здесь воспроизведено чтение с текущей позиции с перемещением перед телом обработки.
Нюансы и выбор. При миграции найдите, зависело ли тело от позиции после each, изменяло ли массив, прерывало ли обход и продолжало позднее. Историческое присваивание массива в цикле могло сбрасывать указатель и зацикливать each; нельзя механически обещать эквивалентность для всех таких программ.
Сравните: current, key, next, reset, list. Выбрать операцию по задаче.
array_randВыбрать один или несколько случайных ключей, сохранив исходный массив.
PHP 4+ · standard
array_rand(array $array, int $num = 1): int|string|arrayВыбрать один или несколько случайных ключей, сохранив исходный массив.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Непустой массив. |
| num | Число выбранных элементов, от 1 до count(array) включительно. |
| Возврат | При num=1 один ключ int/string; иначе массив различных ключей в их исходном порядке. Возвращаются ключи, а не значения и не случайная перестановка выбранного. |
| Отказ и диагностика | PHP 8: ValueError при пустом входе, num<1 или num>count. Раньше E_WARNING и null. |
array_rand и shuffle используют общую глобальную Mt19937-последовательность (с PHP 7.1 вместо libc rand); вызовы других функций с тем же генератором сдвигают её независимо от области видимости. mt_srand/srand с фиксированным seed делают последовательность повторяемой, но не защищённой. Для нового кода PHP Manual рекомендует Random\Randomizer; для непредсказуемости нужен Random\Engine\Secure, а простые безопасные альтернативы — random_int/random_bytes. Это не алгоритм выдачи секретных токенов. Ниже показаны сами выбранные карточки. Фиксированный seed относится только к самостоятельному учебному запуску на указанной версии.
- Для воспроизводимого опыта установить seed 12345.
- Получить ключ a, затем прочитать cards[a].
- Показать человеку текст выбранной карточки.
Здесь нужен видимый выбранный текст. Для проверяемого учебного результата мы явно фиксируем начальное состояние генератора через mt_srand(12345). В самостоятельном файле показанный вывод воспроизведён на PHP 8.5.11; в реальной случайной выдаче фиксированное начальное состояние не задают.
<?php
mt_srand(12345);
$cards = ['a' => 'Руководство', 'b' => 'Пример'];
$key = array_rand($cards);
$title = $cards[$key];
echo 'Выбран ключ: ', $key, "\n";
echo 'Карточка дня: ', $title, "\n";
Ожидаемый результат
Выбран ключ: a
Карточка дня: Руководство
Array_rand возвращает один ключ, здесь a; чтение cards[key] получает текст «Руководство». Именно он показывается человеку. Mt_srand(12345) устанавливает начальное состояние общего генератора, чтобы самостоятельный учебный запуск повторялся на проверенной PHP 8.5.11. До выбора нет других случайных вызовов. В обычной карточке дня фиксированный seed убирают; не обещайте этот конкретный ключ на любой версии или после чужих случайных вызовов.
<?php
mt_srand(12345);
$cards = ['a' => 'Руководство', 'b' => 'Практика', 'c' => 'Задача'];
$keys = array_rand($cards, 2);
foreach ($keys as $key) {
echo 'Карточка ', $key, ': ', $cards[$key], "\n";
}
try { array_rand($cards, 4); }
catch (ValueError $error) { echo "Нельзя выбрать четыре из трёх\n"; }
Ожидаемый результат
Карточка b: Практика
Карточка c: Задача
Нельзя выбрать четыре из трёх
Второй аргумент 2 меняет тип возврата: keys получает массив двух различных ключей. Foreach берёт каждый ключ и показывает его карточку. Порядок выбранных ключей соответствует исходному массиву, а не новой случайной перестановке. Вызов с 4 отвергается ValueError; catch выводит понятное сообщение. Два отдельных вызова num=1 не гарантировали бы две разные карточки. Указанный seed нужен только воспроизводимому учебному опыту.
Нюансы и выбор. Выбор рекламной карточки может допускать такой генератор, токен восстановления — нет. Seed не гарантирует одинаковые последовательности между любыми версиями PHP/алгоритмами. Для перемешанного порядка выбранной группы нужна отдельная операция или Randomizer с явным договором.
Сравните: shuffle, array_keys, array_intersect_key. Выбрать операцию по задаче.
shuffleПеремешать значения на месте, заменив все ключи числовыми индексами.
PHP 4+ · standard
shuffle(array &$array): trueПеремешать значения на месте, заменив все ключи числовыми индексами.
Обозначения перед первым опытом: ключ, значение и чтение через [ ]; вызов, параметры и результат. var_dump показывает тип и значение; echo выводит текст, а "\n" переносит строку. try/catch в опытах с отказом отделяют успешный результат от исключения: разбор обработки ошибок.
| Вход или результат | Договор |
|---|---|
| array | Изменяемая переменная-массив, в том числе пустой. Старые ключи удаляются; если ID важен, храните его внутри записи. |
| Возврат | true; изменённый список находится в array. Указатель сбрасывается в начало. Перемешивание может случайно оставить прежний порядок. |
| Отказ и диагностика | Неверный тип — TypeError. Операция не гарантирует криптографической непредсказуемости или обязательного изменения порядка. |
array_rand и shuffle используют общую глобальную Mt19937-последовательность (с PHP 7.1 вместо libc rand); вызовы других функций с тем же генератором сдвигают её независимо от области видимости. mt_srand/srand с фиксированным seed делают последовательность повторяемой, но не защищённой. Для нового кода PHP Manual рекомендует Random\Randomizer; для непредсказуемости нужен Random\Engine\Secure, а простые безопасные альтернативы — random_int/random_bytes. Это не алгоритм выдачи секретных токенов. Знак & в сигнатуре означает изменение переданной переменной. Учебный seed позволяет увидеть точный порядок в самостоятельном запуске; без такого условия единственного заранее известного порядка нет.
В выводе примеров json_encode только показывает форму результата: [...] — список, {...} — именованные поля. Это отдельное преобразование в текст; как читать такой вывод.
- Исходные значения Адрес,Упаковка,Накладная.
- Установить seed 12345 и перемешать tasks.
- Прочитать полученный порядок с новыми позициями 0/1/2.
<?php
mt_srand(12345);
$tasks = ['a' => 'Адрес', 'b' => 'Упаковка', 'c' => 'Накладная'];
$status = shuffle($tasks);
if ($status) { echo "Порядок подготовлен\n"; }
foreach ($tasks as $position => $task) {
echo 'Позиция ', $position, ': ', $task, "\n";
}
Ожидаемый результат
Порядок подготовлен
Позиция 0: Накладная
Позиция 1: Упаковка
Позиция 2: Адрес
Shuffle меняет tasks на месте, удаляет ключи a/b/c и назначает 0/1/2. Status получает только true; foreach читает реальный новый порядок из tasks. Установленный seed делает этот самостоятельный опыт повторяемым на PHP 8.5.11. Случайная перестановка в общем случае может совпасть с исходной, поэтому функция не обещает обязательного изменения. Здесь задачи независимы: этапы реального процесса с зависимостями перемешивать нельзя.
<?php
mt_srand(12345);
$questions = [['id' => 40, 'text' => 'Что такое переменная?'], ['id' => 70, 'text' => 'Что возвращает функция?']];
shuffle($questions);
foreach ($questions as $position => $question) {
echo 'Вопрос ', $position + 1, ' [ID ', $question['id'], ']: ', $question['text'], "\n";
}
$empty = [];
shuffle($empty);
if ($empty === []) { echo "Пустая подборка осталась пустой\n"; }
Ожидаемый результат
Вопрос 1 [ID 70]: Что возвращает функция?
Вопрос 2 [ID 40]: Что такое переменная?
Пустая подборка осталась пустой
Весь массив каждой карточки перемещается как одно значение, поэтому id и text остаются вместе. Позиция 0/1 — номер выдачи, id 70/40 — постоянный идентификатор для проверки ответа позже. Нельзя было полагаться на прежний внешний ключ карточки: shuffle его заменяет. Пустой массив допустим. Это учебная подборка с фиксированным seed; экзаменационный или конкурсный выбор требует отдельного договора непредсказуемости.
Нюансы и выбор. Не присваивайте $items = shuffle($items): получите true вместо списка. Для сохранения внешних ключей можно перемешать отдельный список ключей и читать исходный словарь по нему. Randomizer удобен для отдельного экземпляра генератора без скрытого общего состояния.
Сравните: array_rand, array_keys, array_values. Выбрать операцию по задаче.
Источники и обсуждения
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


