Любая функция PHP, которая будет отбрасывать свойства объекта, которые являются нулевыми? - PullRequest
17 голосов
/ 04 декабря 2010

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

Ответы [ 6 ]

34 голосов
/ 04 декабря 2010

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

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

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

Это работает путем

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

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

// Strips only null values
$object = (object) array_filter((array) $object, function ($val) {
    return !is_null($val);
});
9 голосов
/ 11 апреля 2013

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

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

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

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

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

2 голосов
/ 04 декабря 2010

Несмотря на название, вы также можете использовать 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
)
1 голос
/ 04 декабря 2010

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

0 голосов
/ 31 января 2019

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

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);
0 голосов
/ 29 марта 2016

Опираясь на ответ @ Гордона , потребуется несколько настроек, чтобы это сработало, но вы также можете использовать array_walk_recursive . Ссылка обязательна, иначе любые изменения, внесенные вами в объект, не будут применяться к области действия за пределами Closure.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...