2010-12-04 2 views
14

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

ответ

27

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

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

Благодаря Gordon's ответ на другой вопрос вчера за предоставленную мне идею.

Это работает

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

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

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

Awesome! Это сработало отлично. Огромное спасибо. Я не уверен, как это происходит, но это очень аккуратный трюк. – Darren 2010-12-04 06:21:57

+0

Я также добавлю объяснение :) – 2010-12-04 06:22:48

2

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

1

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

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

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

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

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

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

0

В ответ на ответ @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); 
Смежные вопросы