任何PHP函数,将剥离属性的一个对象是空的?

jum4pzuy  于 2023-10-15  发布在  PHP
关注(0)|答案(7)|浏览(111)

我返回一个从ORM中提取的对象数组的json_encode()。它包含许多具有空值的属性。删除这些空属性的最简洁的方法是什么?我想我可以遍历属性,看看它们是否为null,然后unset()该属性,但肯定有更优雅的方法吗?

2skhul33

2skhul331#

试试这个;它只对一个简单的对象起作用,但是如果它来自一个ORM,它应该足够简单。

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

感谢戈登昨天对另一个问题的回答给了我这个想法。
这一工程由

  • 将对象转换为关联数组,其中对象属性是键,它们的值是数组值
  • 使用带有默认参数的array_filter来删除带有false的数组项(例如空或null)值
  • 将新数组转换回简单对象

请注意,这将删除所有具有空值的属性,包括空字符串,假布尔值和0,而不仅仅是null;你可以改变array_filter调用,如果你想保留那些并且只远程那些完全为null的。

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

jexiocij2#

我将添加到El Yobo给出的响应中,因为只有当你有一个一维对象或数组时才有效。如果有任何数组或对象嵌套,那么为了让可接受的解决方案工作,您必须创建某种递归数组过滤器。不好
我和我的同事想出的最好的解决方案是在JSON字符串从服务器返回之前对它执行正则表达式。

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

正则表达式将删除格式为,"key":null的字符串中的所有位置,包括前导逗号和键开始之间的任何空格。它还将匹配“key”:null,以确保在JSON对象的开头没有找到空值。
这显然不是最理想的情况,但它将有效地删除空条目,而不必开发某种递归数组过滤器。

yvfmudvl

yvfmudvl3#

除了名字,你也可以使用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
)
ffvjumwh

ffvjumwh4#

没有标准函数可以删除空值属性。如果你写得优雅的话,你自己写一个也不算不优雅。

xmjla07d

xmjla07d5#

我做了这个函数来解决我的问题:清除对象内部的null“对象属性”和“数组属性”。此外,你可以在一个对象中有许多“级别”的对象/数组:

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);
5q4ezhmt

5q4ezhmt6#

根据@Gordon的回答,需要进行一些调整才能实现,但也可以使用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);
envsm3lx

envsm3lx7#

这里是一个实现,应该科普嵌套对象,数组和关联数组的任何组合。需要说明的是,这会创建原始结构的“反空”副本,而不是在原地剥离原始对象或数组。

function filter_nulls($input) {
    $result = new stdClass();
    foreach ($input as $k => $v) {
        if (!is_null($v)) {
            $result->$k = is_scalar($v) ? $v : filter_nulls($v);
        }
    }
    return is_array($input) ? (array) $result : $result;
}

测试:

$someObject = (object) [
    'a' => 1, 
    'b' => 2, 
    'c' => null, 
    'd' => (object) ['da' => 3, 'db' => null], 
    'e' => [null], 
    'f' => ['fa' => (object) ['faa' => 2, 'fab' => null], 'fb' => null]
];

$filteredObject = filter_nulls($someObject);
var_dump($filteredObject);

输出:

object(stdClass)#2 (5) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["d"]=>
  object(stdClass)#1 (1) {
    ["da"]=>
    int(3)
  }
  ["e"]=>
  array(0) {
  }
  ["f"]=>
  array(1) {
    ["fa"]=>
    object(stdClass)#9 (1) {
      ["faa"]=>
      int(2)
    }
  }
}

相关问题