Любая функция PHP, которая лишает свойства объекта, которые являются нулевыми?

Я возвращаю json_encode() из массива объектов, выведенных из ORM. Он содержит множество свойств с нулевым значением. Каков самый простой способ удалить эти свойства, которые являются нулевыми? Я думаю, я мог бы перебирать свойства, посмотреть, являются ли они нулевыми, а затем unset() это свойство, но, безусловно, должен быть более элегантный способ?

Ответ 1

Попробуй это; он будет работать только с простым объектом, но если он исходит от ORM, он должен быть достаточно простым.

// Strips any false-y values
$object = (object) array_filter((array) $object);

Спасибо Гордону за ответ на другой вопрос вчера, что он дал мне идею.

Это работает

  • преобразование объекта в ассоциативный массив, где свойства объекта являются ключами, а их значения являются значениями массива
  • использование array_filter с аргументами по умолчанию для удаления записей массива с ложными (например, пустыми или нулевыми) значениями
  • преобразование нового массива обратно в простой объект

Обратите внимание, что при этом будут удалены все свойства с пустыми значениями, включая пустые строки, ложные логические значения и 0, а не только нули; Вы можете изменить вызов array_filter, если вы хотите сохранить те и только удаленные те, которые точно равны нулю.

// Strips only null values
$object = (object) array_filter((array) $object, function ($val) {
    return !is_null($val);
});

Ответ 2

Я собираюсь добавить к ответу, данному El Yobo, потому что это будет работать, только если у вас есть 1 мерный объект или массив. Если есть какой-либо массив или объект, то для того, чтобы заставить принятое решение работать, вы должны создать какой-то рекурсивный фильтр массива. Нехорошо.

Лучшее решение, с которым я столкнулся с моим коллегой, состояло в том, чтобы фактически выполнить регулярное выражение в строке JSON до того, как оно было возвращено с сервера.

$json = json_encode($complexObject);
echo preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $json);

Регулярное выражение удалит все места в строке формы ,"key":null, включая пробелы между ведущей запятой и началом ключа. Он также будет соответствовать "key": null, после чего убедитесь, что в начале объекта JSON не было найдено нулевых значений.

Это, очевидно, не самая идеальная ситуация, но она эффективно удалит нулевые записи, не создавая какой-то рекурсивный фильтр массива.

Ответ 3

Несмотря на название, вы также можете использовать array_walk с закрытием:

// Setup
$obj = (object) array('foo' => NULL, 'bar' => 'baz');

// equivalent to array_filter
array_walk($obj, function($v,$k) use ($obj) {
    if(empty($v)) unset($obj->$k);
});

// output
print_r($obj);

Выход

stdClass Object
(
    [foo] => bar
)

Ответ 4

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

Ответ 5

Построение ответа @Gordon потребует нескольких корректировок для выполнения этой работы, но вы также можете использовать array_walk_recursive. Требуется ссылка или любые изменения, внесенные вами в объект, не будут применяться к области вне Закрытия.

IE:

$someObject = (array)$someObject;
array_walk_recursive($someObject, function($v,$k) use (&$someObject) {
    if($someObject[$k] == null) {
        unset($someObject[$k]);
    }
});

$someObject = (object)$someObject;

var_dump($someObject);

Ответ 6

Я сделал эту функцию, которая решает мою проблему: очистить нулевые "свойства объекта" и "свойства массива" внутри объекта. Кроме того, вы можете иметь много "уровней" объектов/массивов внутри объекта:

function cleanNullsOfObject(&$object) {
    foreach ($object as $property => &$value) {
        if (is_object($value)) {
            cleanNullsOfObject($value);
            if (empty(get_object_vars($value))) {
                unset($object->$property);
            }
        }
        if (is_array($value) && is_object($value[0])) {
            foreach ($value as $val) {
                cleanNullsOfObject($val);
            }
        }
        if (is_null($value) || (is_array($value) && empty($value))) {
            unset($object->$property);
        }
    }
}
//test
$object = new stdClass();
$object->property = "qwe";
$object->nullProperty = null;
$propertyObject = new stdClass();
$propertyObject->property = "asd";
$propertyObject->nullProperty = null;
$object->propertyObject = $propertyObject;
var_dump($object);
echo "<br>";
echo "<br>";
cleanNullsOfObject($object);
var_dump($object);