Работа с ассоциативными массивами в языке PHP

Раздел: 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.

Ассоциативные массивы в PHP - comments

En
ассоциативный массив php (php)