Работа с ассоциативными массивами в языке PHP
Основы ассоциативных массивов в PHP
Наиболее эффективный способ создания и использования
Ассоциативные массивы позволяют хранить данные в парах ключ => значение. В PHP принято использовать короткий синтаксис с квадратными скобками (доступен с PHP 5.4). Такой код компактен и легко читается.
$user = [
'name' => 'Иван',
'age' => 30,
'email' => 'ivan@example.com'
];
Обращение к элементам происходит по ключу:
echo $user['name']; // Иван
Иван
Если ключ не указан, PHP автоматически присваивает числовой индекс, начиная с 0. Но для ассоциативного массива это не характерно.
Распространённые ошибки:
- Обращение к несуществующему ключу вызывает предупреждение
Warning: Undefined array key. Рекомендуется предварительно проверять наличие ключа. - Путаница между
issetиarray_key_existsпри значенииnull.
Как создать ассоциативный массив разными способами?
Помимо короткого синтаксиса, можно использовать функцию array():
$user = array(
'name' => 'Мария',
'age' => 25
);
Также массив можно построить динамически, присваивая значения:
$user['name'] = 'Петр';
$user['age'] = 35;
При этом изначально переменная может быть не определена. PHP автоматически создаст массив.
Проблема:
Если случайно использовать числовой ключ, который совпадает с автоматическим индексом, может возникнуть путаница. Рекомендуется явно указывать ключи.
Как добавить новый элемент в ассоциативный массив?
$user['phone'] = '+7-900-123-45-67';
Если ключ уже существует, значение будет перезаписано. Если ключа нет, он будет создан.
print_r($user);
/*
Array
(
[name] => Петр
[age] => 35
[phone] => +7-900-123-45-67
)
*/
Как изменить значение по существующему ключу?
$user['age'] = 36;
Простое присваивание новому значению.
Как удалить элемент по ключу?
unset($user['phone']);
После удаления ключ и значение исчезают. Массив не переиндексируется.
print_r($user);
/*
Array
(
[name] => Петр
[age] => 36
)
*/
Важно:
При удалении элементов циклический перебор с использованием foreach может вести себя непредсказуемо, если массив модифицируется во время итерации. Рекомендуется сначала собрать ключи для удаления, а затем удалить.
Как проверить, существует ли ключ в массиве?
if (array_key_exists('email', $user)) {
echo 'Ключ email существует';
}
if (isset($user['email'])) {
echo 'Значение email не null';
}
Разница: array_key_exists возвращает true, даже если значение равно null. isset вернёт false в этом случае.
// Если $user['email'] = null, то:
// array_key_exists('email', $user) -> true
// isset($user['email']) -> false
Как перебрать все элементы ассоциативного массива?
Основной способ - цикл foreach:
foreach ($user as $key => $value) {
echo "$key: $value\n";
}
Можно получить только значения, если опустить ключ:
foreach ($user as $value) {
echo "$value\n";
}
Как получить все ключи или все значения?
$keys = array_keys($user);
$values = array_values($user);
print_r($keys);
print_r($values);
Array
(
[0] => name
[1] => age
)
Array
(
[0] => Петр
[1] => 36
)
Как объединить два ассоциативных массива?
Оператор + добавляет элементы второго массива, не перезаписывая существующие ключи:
$extra = ['city' => 'Москва', 'name' => 'Анна'];
$result = $user + $extra;
print_r($result);
// name останется Петр, добавится city
Array
(
[name] => Петр
[age] => 36
[city] => Москва
)
Для перезаписи значений по одинаковым ключам используется array_merge:
$result = array_merge($user, $extra);
print_r($result);
// name станет Анна
Array
(
[name] => Анна
[age] => 36
[city] => Москва
)
Как отсортировать ассоциативный массив по ключам или по значениям?
Для сортировки по ключам (по возрастанию) используется ksort:
$fruits = ['banana' => 3, 'apple' => 5, 'cherry' => 2];
ksort($fruits);
print_r($fruits);
Array
(
[apple] => 5
[banana] => 3
[cherry] => 2
)
Для сортировки по значениям (с сохранением ключей) - asort:
asort($fruits);
print_r($fruits);
Array
(
[cherry] => 2
[banana] => 3
[apple] => 5
)
Если нужно изменить порядок на обратный, применяются krsort и arsort. Важно: эти функции сортируют исходный массив, а не возвращают новый.
Расширенные примеры работы с ассоциативными массивами
Ниже приведены более сложные сценарии, которые часто встречаются на практике.
Многомерные ассоциативные массивы
Массив может содержать другие массивы в качестве значений. Это удобно для представления иерархических данных, например, списка пользователей с их свойствами.
$users = [
'user1' => [
'name' => 'Иван',
'age' => 30,
'skills' => ['PHP', 'MySQL', 'JavaScript']
],
'user2' => [
'name' => 'Мария',
'age' => 25,
'skills' => ['Python', 'Django']
]
];
// Доступ к вложенному элементу
echo $users['user1']['skills'][0]; // PHP
PHP
Для перебора многомерного массива используется вложенный цикл:
foreach ($users as $id => $data) {
echo "Пользователь $id:\n";
foreach ($data as $key => $value) {
if (is_array($value)) {
echo " $key: " . implode(', ', $value) . "\n";
} else {
echo " $key: $value\n";
}
}
}
Пользователь user1: name: Иван age: 30 skills: PHP, MySQL, JavaScript Пользователь user2: name: Мария age: 25 skills: Python, Django
Фильтрация массива по условию (array_filter)
Функция array_filter позволяет отфильтровать элементы, используя callback. По умолчанию удаляются элементы с пустыми значениями (false, null, '' и т.д.).
$users = [
['name' => 'Anna', 'active' => true],
['name' => 'Bob', 'active' => false],
['name' => 'Eve', 'active' => true]
];
$activeUsers = array_filter($users, function($user) {
return $user['active'] === true;
});
print_r($activeUsers);
Array
(
[0] => Array
(
[name] => Anna
[active] => 1
)
[2] => Array
(
[name] => Eve
[active] => 1
)
)
Обратите внимание, что ключи сохраняются. Для сброса индексов можно добавить array_values.
Применение функции к каждому элементу (array_map)
array_map возвращает новый массив, где к каждому значению применена указанная функция.
$prices = ['apple' => 100, 'banana' => 50, 'cherry' => 200];
$pricesWithTax = array_map(function($price) {
return $price * 1.2;
}, $prices);
print_r($pricesWithTax);
Array
(
[apple] => 120
[banana] => 60
[cherry] => 240
)
Ключи при этом сохраняются.
Сортировка с пользовательской функцией (usort, uasort, uksort)
Для нестандартных критериев сортировки применяются функции usort (по значениям, сбрасывая ключи), uasort (по значениям с сохранением ключей), uksort (по ключам).
$products = [
['name' => 'Книга', 'price' => 500],
['name' => 'Ручка', 'price' => 50],
['name' => 'Тетрадь', 'price' => 100]
];
// Сортировка по цене (по возрастанию) с сохранением ключей
uasort($products, function($a, $b) {
return $a['price'] <=> $b['price'];
});
print_r($products);
Array
(
[1] => Array
(
[name] => Ручка
[price] => 50
)
[2] => Array
(
[name] => Тетрадь
[price] => 100
)
[0] => Array
(
[name] => Книга
[price] => 500
)
)
Рекурсивный обход многомерного массива
Для обхода массива неизвестной глубины используется рекурсивная функция или RecursiveArrayIterator.
function printAll($data, $prefix = '') {
foreach ($data as $key => $value) {
if (is_array($value)) {
printAll($value, $prefix . $key . '.');
} else {
echo $prefix . $key . ': ' . $value . "\n";
}
}
}
$nested = [
'config' => [
'db' => ['host' => 'localhost', 'port' => 3306],
'app' => ['debug' => false]
]
];
printAll($nested);
config.db.host: localhost config.db.port: 3306 config.app.debug:
Использование array_reduce для свёртки массива
array_reduce применяет callback к элементам массива, накапливая результат.
$items = [
['price' => 200, 'qty' => 2],
['price' => 100, 'qty' => 3],
];
$total = array_reduce($items, function($carry, $item) {
return $carry + $item['price'] * $item['qty'];
}, 0);
echo "Итого: $total";
Итого: 700
Преобразование массива в JSON и обратно
Ассоциативные массивы легко конвертируются в JSON, что полезно для API.
$data = ['name' => 'Анна', 'age' => 28];
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
echo $json;
$decoded = json_decode($json, true); // второй параметр true для получения массива
print_r($decoded);
{"name":"Анна","age":28}
Array
(
[name] => Анна
[age] => 28
)
Объединение массивов с помощью array_replace
array_replace заменяет значения первого массива значениями из последующих по одинаковым ключам. Принцип похож на array_merge, но отличается поведением для числовых ключей (не переиндексирует).
$base = ['a' => 1, 'b' => 2, 'c' => 3];
$override = ['b' => 20, 'd' => 4];
$result = array_replace($base, $override);
print_r($result);
Array
(
[a] => 1
[b] => 20
[c] => 3
[d] => 4
)
Проблема с плавающими ключами
Если использовать число с плавающей точкой в качестве ключа, PHP преобразует его к целому с потерей дробной части:
$arr = [1.5 => 'val'];
var_dump($arr);
array(1) {
[1] =>
string(3) "val"
}
Поэтому рекомендуется явно приводить ключи к строке, если важна точность.
Использование ключа с пробелами и специальными символами
Ключи могут содержать пробелы, но для обращения их нужно заключать в кавычки:
$data = ['full name' => 'Иван Петров'];
echo $data['full name'];
Иван Петров
Это может быть неудобно, поэтому лучше использовать нотацию camelCase или snake_case.