Table of Contents
Функция array_keys() возвращает все ключи из массива.
Простой пример
$data = [
'name' => 'Alex',
'age' => 25,
'country' => 'Ukraine'
];
$keys = array_keys($data);
print_r($keys);
// Output
Array
(
[0] => name
[1] => age
[2] => country
)
Пример с поиском значения
Ты можешь искать ключи по значению:
$data = ['apple', 'banana', 'apple', 'cherry'];
$keys = array_keys($data, 'apple');
print_r($keys);
// Output
Array
(
[0] => 0
[1] => 2
)
То есть array_keys() нашла, где в массиве находится значение 'apple'.
💡 Задача: Найти пользователей, у которых статус — “active”, и вывести их имена
У тебя есть массив пользователей в виде ассоциативного массива, где ключ — это ID пользователя, а значение — массив с именем и статусом. Твоя цель — вывести имена только активных пользователей.
Исходный массив:
$users = [
101 => ['name' => 'Alice', 'status' => 'active'],
102 => ['name' => 'Bob', 'status' => 'inactive'],
103 => ['name' => 'Charlie', 'status' => 'active'],
104 => ['name' => 'Diana', 'status' => 'banned'],
105 => ['name' => 'Eve', 'status' => 'active'],
];
Решение (пошагово):
- Создадим массив статусов.
- С помощью
array_keys()найдём ID пользователей со статусом'active'. - Выведем имена этих пользователей по ID.
$users = [
101 => ['name' => 'Alice', 'status' => 'active'],
102 => ['name' => 'Bob', 'status' => 'inactive'],
103 => ['name' => 'Charlie', 'status' => 'active'],
104 => ['name' => 'Diana', 'status' => 'banned'],
105 => ['name' => 'Eve', 'status' => 'active'],
];
// 1. Соберём массив статусов по ID
$statuses = array_column($users, 'status');
// [
101 => 'active',
102 => 'inactive',
103 => 'active',
104 => 'banned',
105 => 'active'
]
// 2. Найдём ID пользователей со статусом "active"
$active_ids = array_keys($statuses, 'active');
// [101, 103, 105];
// 3. Выведем имена активных пользователей
foreach ($active_ids as $id) {
echo $users[$id]['name'] . PHP_EOL;
}
Результат:
Alice
Charlie
Eve
💼 Задача:
У тебя есть массив заказов из интернет-магазина. Нужно:
- Найти всех пользователей, у которых есть хотя бы один оплаченный заказ.
- Из них — выбрать только тех, кто сделал более одного заказа.
- Вывести имена этих пользователей.
И всё это сделать с помощью array_keys() (и других функций, конечно).
Исходные данные:
$orders = [
['user_id' => 1, 'name' => 'Anna', 'status' => 'paid'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'pending'],
['user_id' => 1, 'name' => 'Anna', 'status' => 'pending'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid'],
['user_id' => 4, 'name' => 'Dmitry', 'status' => 'cancelled'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'pending'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid'],
];
Логика решения:
- Считаем, сколько заказов сделал каждый пользователь.
- Проверим, у кого есть хотя бы один
status == 'paid'. - Оставим только тех, у кого больше одного заказа.
- Используем
array_keys()для фильтрации нужныхuser_id.
Решение:
$orders = [
['user_id' => 1, 'name' => 'Anna', 'status' => 'paid'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'pending'],
['user_id' => 1, 'name' => 'Anna', 'status' => 'pending'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid'],
['user_id' => 4, 'name' => 'Dmitry', 'status' => 'cancelled'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid'],
];
// Шаг 1. Считаем количество заказов для каждого user_id
$order_counts = [];
$paid_users = [];
foreach ($orders as $order) {
$id = $order['user_id'];
// Считаем заказы
if (!isset($order_counts[$id])) {
$order_counts[$id] = 0;
}
$order_counts[$id]++;
// Отмечаем, если есть оплаченный заказ
if ($order['status'] === 'paid') {
$paid_users[$id] = $order['name']; // сохраняем имя
}
}
// Шаг 2. Отбираем тех, у кого более одного заказа
$multiple_orders_ids = array_keys(array_filter($order_counts, fn($count) => $count > 1));
// Шаг 3. Отбираем тех, кто есть и в paid_users, и у кого >1 заказ
$final_ids = array_intersect(array_keys($paid_users), $multiple_orders_ids);
// Шаг 4. Выводим имена
foreach ($final_ids as $id) {
echo $paid_users[$id] . PHP_EOL;
}
// Output
Anna
Boris
Clara
У всех троих есть хотя бы один оплаченный заказ и более одного заказа всего.
Усложним задачу.
Теперь подключим дату заказа, и добавим фильтрацию по дате, чтобы выбрать только пользователей, которые:
Найди всех пользователей, у которых более одного заказа, хотя бы один из которых был оплачен за последние 30 дней. Выведи их имена.
Обновлённый массив заказов:
$orders = [
['user_id' => 1, 'name' => 'Anna', 'status' => 'paid', 'date' => '2025-04-01'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'pending', 'date' => '2025-03-10'],
['user_id' => 1, 'name' => 'Anna', 'status' => 'pending', 'date' => '2025-03-20'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid', 'date' => '2025-04-10'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid', 'date' => '2025-02-15'],
['user_id' => 4, 'name' => 'Dmitry', 'status' => 'cancelled', 'date' => '2025-04-01'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid', 'date' => '2025-01-15'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid', 'date' => '2025-04-02'],
];
📅 Текущая дата: 2025-04-15
✅ Алгоритм:
- Считаем количество заказов на пользователя.
- Ищем пользователей, у которых есть хотя бы один оплаченный заказ за последние 30 дней.
- Оставляем только тех, у кого больше одного заказа.
- Выводим имена.
💡 Решение:
$orders = [
['user_id' => 1, 'name' => 'Anna', 'status' => 'paid', 'date' => '2025-04-01'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'pending', 'date' => '2025-03-10'],
['user_id' => 1, 'name' => 'Anna', 'status' => 'pending', 'date' => '2025-03-20'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid', 'date' => '2025-04-10'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid', 'date' => '2025-02-15'],
['user_id' => 4, 'name' => 'Dmitry', 'status' => 'cancelled', 'date' => '2025-04-01'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid', 'date' => '2025-01-15'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid', 'date' => '2025-04-02'],
];
$now = new DateTime('2025-04-15');
$days_back = new DateInterval('P30D');
$cutoff = $now->sub($days_back);
$order_counts = [];
$recent_paid_users = [];
foreach ($orders as $order) {
$id = $order['user_id'];
$date = new DateTime($order['date']);
// Считаем количество заказов
if (!isset($order_counts[$id])) {
$order_counts[$id] = 0;
}
$order_counts[$id]++;
// Если оплачен и за последние 30 дней — добавляем
if ($order['status'] === 'paid' && $date > $cutoff) {
$recent_paid_users[$id] = $order['name'];
}
}
// Пользователи с >1 заказом
$multiple_orders_ids = array_keys(array_filter($order_counts, fn($count) => $count > 1));
// Совпадение по user_id
$final_ids = array_intersect(array_keys($recent_paid_users), $multiple_orders_ids);
// Вывод
foreach ($final_ids as $id) {
echo $recent_paid_users[$id] . PHP_EOL;
}
// Output
Anna
Clara
Boris
Новая задача:
Найди пользователей, у которых минимум 2 оплаченных заказа за последние 30 дней.
Выведи их имена и количество таких заказов.
Данные всё те же:
$orders = [
['user_id' => 1, 'name' => 'Anna', 'status' => 'paid', 'date' => '2025-04-01'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'pending', 'date' => '2025-03-10'],
['user_id' => 1, 'name' => 'Anna', 'status' => 'pending', 'date' => '2025-03-20'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid', 'date' => '2025-04-10'],
['user_id' => 3, 'name' => 'Clara', 'status' => 'paid', 'date' => '2025-02-15'],
['user_id' => 4, 'name' => 'Dmitry', 'status' => 'cancelled', 'date' => '2025-04-01'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid', 'date' => '2025-01-15'],
['user_id' => 2, 'name' => 'Boris', 'status' => 'paid', 'date' => '2025-04-02'],
];
Решение:
$now = new DateTime('2025-04-15');
$cutoff = (clone $now)->sub(new DateInterval('P30D'));
$paid_counts = [];
$user_names = [];
foreach ($orders as $order) {
$id = $order['user_id'];
$date = new DateTime($order['date']);
// Сохраняем имя
$user_names[$id] = $order['name'];
// Считаем оплаченные заказы за последние 30 дней
if ($order['status'] === 'paid' && $date > $cutoff) {
if (!isset($paid_counts[$id])) {
$paid_counts[$id] = 0;
}
$paid_counts[$id]++;
}
}
// Фильтруем тех, у кого 2+ оплаченных заказов за последние 30 дней
$filtered_users = array_filter($paid_counts, fn($count) => $count >= 2);
// Выводим результат
foreach ($filtered_users as $id => $count) {
echo "{$user_names[$id]}: $count заказ(а/ов) за последние 30 дней" . PHP_EOL;
}
// Output
Clara: 2 заказ(а/ов) за последние 30 дней
📌 Пояснение:
- Clara: 2 оплаченных заказа, один 10 апреля и один 15 февраля → второй слишком старый, но первый 10 апреля засчитывается, а второй оплаченный нет.
Ой! Стоп! 😅
Clara:
2025-04-10— ✅2025-02-15— ❌ (старый)
Значит у неё только 1, а не 2. 🤯
Нужно пересчитать!
Правильный результат:
- Anna: 1 оплаченный заказ — ❌
- Boris: 1 оплаченный в 30 дней — ❌
- Clara: 1 — ❌
👉 Никто не прошёл условие>= 2 заказов за 30 дней
