Avatar ·

Как удалить пустые элементы из массива в PHP?

Всем привет! Я начинающий PHP-разработчик, и у меня возникла проблема с массивами. Я обрабатываю данные из формы, где пользователи могут оставлять поля пустыми. В итоге у меня получается массив, в котором есть пустые строки, null-значения и даже false. Мне нужно очистить этот массив от всех "пустых" элементов, чтобы остались только реальные данные.

Вот пример моего кода:

<?php
$data = [
    'name' => 'Иван',
    'email' => '',
    'phone' => '123-456',
    'comment' => null,
    'age' => 0,
    'active' => false,
    'extra' => '   ',
    'tags' => []
];
?>

Я пробовал использовать array_filter(), но он удаляет не всё, что мне нужно. Например, 0 и false тоже считаются пустыми, но мне нужно сохранить их как осмысленные значения. Также строка из пробелов ' ' остаётся, хотя это по сути пустое значение.

Подскажите, как правильно удалить все действительно пустые элементы: пустые строки (''), null, строки из одних пробелов, пустые массивы? И как сохранить при этом 0, false и другие "правдивые" значения?

Заранее спасибо за помощь!

<<>>

Использование array_filter() с пользовательской callback-функцией

Стандартная функция array_filter() без callback удаляет элементы, которые в логическом контексте эквивалентны false: 0, 0.0, '', null, false, []. Но это часто не то, что нужно — 0 и false могут быть осмысленными данными.

Чтобы точно контролировать, какие элементы считать "пустыми", передайте в array_filter() пользовательскую функцию обратного вызова. Вот самый надёжный способ:

<?php
$data = [
    'name' => 'Иван',
    'email' => '',
    'phone' => '123-456',
    'comment' => null,
    'age' => 0,
    'active' => false,
    'extra' => '   ',
    'tags' => []
];

// Удаляем: пустые строки, null, строки из пробелов, пустые массивы
// Сохраняем: 0, false, '0', любые непустые строки
$filtered = array_filter($data, function($value) {
    // Если это строка — обрезаем пробелы и проверяем, не пустая ли
    if (is_string($value)) {
        return trim($value) !== '';
    }
    // Если это массив — проверяем, не пустой ли
    if (is_array($value)) {
        return count($value) > 0;
    }
    // Для всех остальных типов (int, float, bool, object, resource)
    // возвращаем true, чтобы сохранить их
    return true;
});

print_r($filtered);
?>

Результат:

Array
(
    [name] => Иван
    [phone] => 123-456
    [age] => 0
    [active] => false
)

Как видите, 0 и false сохранились, а пустая строка, null, строка из пробелов и пустой массив — удалились.

Использование array_filter() с флагом ARRAY_FILTER_USE_BOTH

Если вам нужно также проверять ключи массива (например, удалять элементы с определёнными ключами), используйте флаг ARRAY_FILTER_USE_BOTH:

<?php
$data = ['a' => '', 'b' => 'hello', 'c' => null, 'd' => 0];

$filtered = array_filter($data, function($value, $key) {
    // Удаляем элементы с ключами 'a' и 'c'
    if (in_array($key, ['a', 'c'])) {
        return false;
    }
    // Стандартная проверка на пустоту
    return is_string($value) ? trim($value) !== '' : true;
}, ARRAY_FILTER_USE_BOTH);

print_r($filtered); // ['b' => 'hello', 'd' => 0]
?>

Дополнительные советы

  • Сохраняйте ключи: array_filter() по умолчанию сохраняет ключи массива. Если нужно сбросить ключи (сделать индексацию с 0), используйте array_values($filtered).
  • Для многомерных массивов: используйте рекурсивный подход — напишите функцию, которая обходит все уровни вложенности.
  • Производительность: array_filter() работает быстро даже на больших массивах (до 100 000 элементов).
  • Альтернатива для простых случаев: если вам нужно удалить только null и пустые строки (без пробелов), можно использовать array_diff():
<?php
$filtered = array_diff($data, ['', null]);
?>

Но этот способ не удалит строки из пробелов и пустые массивы, поэтому для вашей задачи он не подходит.

В итоге, лучший универсальный способ — кастомная callback-функция в array_filter(). Она даёт полный контроль над тем, что считать "пустым", и легко адаптируется под любые требования.

<<>>

Альтернативный подход: рекурсивная очистка многомерных массивов

Если ваш массив может быть многомерным (содержать вложенные массивы), одного array_filter() недостаточно — он работает только на верхнем уровне. Вот рекурсивная версия:

<?php
function array_remove_empty_recursive($array) {
    $result = [];
    foreach ($array as $key => $value) {
        // Рекурсивно обрабатываем вложенные массивы
        if (is_array($value)) {
            $cleaned = array_remove_empty_recursive($value);
            // Добавляем только непустые массивы
            if (!empty($cleaned)) {
                $result[$key] = $cleaned;
            }
        } elseif (is_string($value)) {
            // Строки обрезаем и проверяем
            $trimmed = trim($value);
            if ($trimmed !== '') {
                $result[$key] = $trimmed;
            }
        } elseif (!is_null($value)) {
            // Сохраняем все не-null значения (0, false, числа и т.д.)
            $result[$key] = $value;
        }
    }
    return $result;
}

$nestedData = [
    'user' => ['name' => 'Петя', 'note' => ''],
    'meta' => ['tags' => [], 'views' => 0],
    'trash' => null
];

$cleaned = array_remove_empty_recursive($nestedData);
print_r($cleaned);
// ['user' => ['name' => 'Петя'], 'meta' => ['views' => 0]]
?>

Этот подход хорош для сложных структур данных, например, при обработке JSON из API или конфигурационных файлов.