Я возвращаю json_encode () из массива объектов, выведенных из ORM. Он содержит множество свойств с нулевым значением. Каков самый простой способ удалить эти свойства, которые являются нулевыми? Я думаю, я мог бы перебирать свойства, посмотреть, являются ли они нулевыми, а затем unset () это свойство, но, безусловно, должен быть более элегантный способ?
Попробуй это; он будет работать только на простой объект, но если он исходит из ORM, он должен быть достаточно простым.
// Strips any false-y values $object = (object) array_filter((array) $object);
Спасибо Гордону ответить на другой вопрос вчера за то, что он дал мне эту идею.
Это работает
Обратите внимание, что это приведет к удалению всех свойств с пустыми значениями, включая пустые строки, ложные логические значения и 0, а не только нули; вы можете изменить вызов array_filter, если хотите сохранить эти и только удаленные те, которые точно равны нулю.
// Strips only null values $object = (object) array_filter((array) $object, function ($val) { return !is_null($val); });
Я собираюсь добавить к ответу, данному El Yobo, потому что это будет работать только в том случае, если у вас есть 1-мерный объект или массив. Если есть какой-либо массив или объект, то для того, чтобы заставить принятое решение работать, вы должны создать какой-то рекурсивный фильтр массива. Нехорошо.
Лучшее решение, с которым я столкнулся с коллегой, состояло в том, чтобы фактически выполнить регулярное выражение в строке JSON до того, как оно было возвращено с сервера.
$json = json_encode($complexObject); echo preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $json);
Регулярное выражение удалит все места в строке формы ,"key":null
включая пробелы между ведущей запятой и началом ключа. Он также будет соответствовать «key»: null, после чего убедитесь, что в начале объекта JSON не было найдено нулевых значений.
Это, очевидно, не самая идеальная ситуация, но она эффективно удалит нулевые записи, не создавая какой-то рекурсивный фильтр массива.
Нет стандартной функции для удаления нулевых свойств. Написание одного из ваших не является неэлегантным, если вы пишете один из них элегантно.
Несмотря на название, вы также можете использовать 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 )
Создав ответ @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);
с$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);