PHP从对象中删除空项

时间:2018-05-04 17:17:34

标签: php arrays json object

我有以下对象,这里打印为数组。该对象是根据SOAP请求构建的。

AdminInfo Object (
  [Supplier] => Supplier Object (
      [Party] => Party Object (
          [OrgInfo] => OrgInfo Object (
              [CompanyName] => Bobs
              [IDInfo] => Array of IDInfo Objects (
                  [0] => IDInfo Object (
                      [IDQualifierCode] => 
                      [IDNum] => 
                    )
                  [1] => IDInfo Object (
                      [IDQualifierCode] => CompanyID
                      [IDNum] => 83e26599-d40g-4cba-9791-7d7c83de282c
                    )
                  [2] => IDInfo Object (
                      [IDQualifierCode] => TID
                      [IDNum] => BOBTID01020304
                    )
                  [3] => IDInfo Object (
                      [IDQualifierCode] => Token
                      [IDNum] => c784570e-044d-42c8-98fe-af9f7c1747f5
                    )
                )
            )
          [ContactInfo] => ContactInfo Object (
              [ContactJobTitle] => 
              [Communications] => Comm Object (
                  [CommQualifier] => 
                  [CommPhone] => 
                  [CommEmail] => 
                  [Address] => Address Object (
                      [Address1] => 
                      [Address2] => 
                      [City] => 
                      [StateProvince] => 
                      [PostalCode] => 
                      [CountryCode] => 
                    )
                )
              [ContactName] => PersonName Object (
                  [FirstName] => 
                  [MiddleName] => 
                  [LastName] => 
                )
            )
        )
    )
  [Company] => Company Object (
      [Party] => Party Object (
          [OrgInfo] => OrgInfo Object (
              [CompanyName] => SF
              [IDInfo] => 
            )
          [ContactInfo] => 
        )
    )
  [Facility] => Facility Object (
      [Party] => Party Object (
          [OrgInfo] => Array of OrgInfo Objects (
            )
          [ContactInfo] => ContactInfo Object (
              [ContactJobTitle] => Owner
              [Communications] => Array of Comm Objects(
                  [0] => Comm Object (
                        [CommQualifier] => WP
                        [CommPhone] => 1234567890
                    )
                  [1] => Comm Object (
                        [CommQualifier] => SA
                        [Address] => Address Object (
                            [Address1] => 123 NE 14th St 
                            [City] => Nowhere
                            [StateProvince] => ND
                            [PostalCode] => 12345
                            [CountryCode] => US
                          )
                      )
                  [2] => 
                  [3] => 
                )
              [ContactName] => PersonName Object (
                  [FirstName] => Bob
                  [MiddleName] => 
                  [LastName] => Tester
                )
            )
        )
    )
)

我想要做的是删除所有空元素并使用此对象返回

AdminInfo Object (
  [Supplier] => Supplier Object (
      [Party] => Party Object (
          [OrgInfo] => OrgInfo Object (
              [CompanyName] => Bobs
              [IDInfo] => Array of IDInfo Objects (
                  [0] => IDInfo Object (
                      [IDQualifierCode] => 
                      [IDNum] => 
                    )
                  [1] => IDInfo Object (
                      [IDQualifierCode] => CompanyID
                      [IDNum] => 83e26599-d40g-4cba-9791-7d7c83de282c
                    )
                  [2] => IDInfo Object (
                      [IDQualifierCode] => TID
                      [IDNum] => BOBTID01020304
                    )
                  [3] => IDInfo Object (
                      [IDQualifierCode] => Token
                      [IDNum] => c784570e-044d-42c8-98fe-af9f7c1747f5
                    )
                )
            )
        )
    )
  [Company] => Company Object (
      [Party] => Party Object (
          [OrgInfo] => OrgInfo Object (
              [CompanyName] => SF
            )
        )
    )
  [Facility] => Facility Object (
      [Party] => Party Object (
          [ContactInfo] => ContactInfo Object (
              [ContactJobTitle] => Owner
              [Communications] => Array of Comm Objects (
                  [0] => Comm Object (
                        [CommQualifier] => WP
                        [CommPhone] => 1234567890
                    )
                  [1] => Comm Object (
                        [CommQualifier] => SA
                        [Address] => Address Object (
                            [Address1] => 123 NE 14th St 
                            [City] => Nowhere
                            [StateProvince] => ND
                            [PostalCode] => 12345
                            [CountryCode] => US
                          )
                      )
                )
              [ContactName] => PersonName Object (
                  [FirstName] => Bob
                  [LastName] => Tester
                )
            )
        )
    )
)

这些尝试根本不做;变量$AdminInfo是上面的对象......

从此处的解决方案:strip null values of json object

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

从此处的解决方案:How to remove null values from an array?

$json = json_encode($AdminInfo);                // convert to JSON
$arr = (array)json_decode($json);               // convert to an array
$object = (object) array_filter((array) $arr);  // filter the array
$result = json_encode($object);                 // convert it back to JSON
echo $result;

从这里开始:PHP - How to remove empty entries of an array recursively?

function array_remove_empty($haystack)
{
    foreach ($haystack as $key => $value) {
        if (is_array($value)) {
            $haystack[$key] = array_remove_empty($haystack[$key]);
        }

        if (empty($value)) {
            unset($haystack[$key]);
        }
    }

    return $haystack;
}

$json = json_encode($AdminInfo);          // convert to JSON
$arr = (array)json_decode($json);         // convert to an array
print_r(array_remove_empty($arr));        // run through array_remove_empty function and print

从此处的解决方案:Remove items from multidimensional array in PHP

function cleanArray($array) {
    if (is_array($array)) {
        foreach ($array as $key => $sub_array)
        {
            $result = cleanArray($sub_array);
            if ($result === false) {
                unset($array[$key]);
            } else {
                $array[$key] = $result;
            }
        }
    }
    if (empty($array)) {
        return false;
    }
    return $array;
}

$json = json_encode($AdminInfo);          // convert to JSON
$arr = (array)json_decode($json);         // convert to an array
print_r(cleanArray($arr));                // run through cleanArray function and print

修改
AdminInfo对象为JSON:

{
    "Supplier":{
        "Party":{
            "OrgInfo":{
                "CompanyName":"Bobs",
                "IDInfo":[
                    {
                        "IDQualifierCode":null,
                        "IDNum":""
                    },
                    {
                        "IDQualifierCode":"CompanyID",
                        "IDNum":"83e26599-d40g-4cba-9791-7d7c83de282c"
                    },
                    {
                        "IDQualifierCode":"TID",
                        "IDNum":"BOBTID01020304"
                    },
                    {
                        "IDQualifierCode":"Token",
                        "IDNum":"c784570e-044d-42c8-98fe-af9f7c1747f5"
                    }
                ]
            },
            "ContactInfo":{
                "ContactJobTitle":"",
                "Communications":{
                    "CommQualifier":null,
                    "CommPhone":"",
                    "CommEmail":"",
                    "Address":{
                        "Address1":"",
                        "Address2":"",
                        "City":"",
                        "StateProvince":null,
                        "PostalCode":"",
                        "CountryCode":null
                    }
                },
                "ContactName":{
                    "FirstName":"",
                    "MiddleName":"",
                    "LastName":""
                }
            }
        }
    },
    "Company":{
        "Party":{
            "OrgInfo":{
                "CompanyName":"SF",
                "IDInfo":null
            },
            "ContactInfo":null
        }
    },
    "Facility":{
        "Party":{
            "OrgInfo":[

            ],
            "ContactInfo":{
                "ContactJobTitle":"",
                "Communications":[
                    {
                        "CommQualifier":null,
                        "CommPhone":"",
                        "CommEmail":"",
                        "Address":{
                            "Address1":"",
                            "Address2":"",
                            "City":"",
                            "StateProvince":null,
                            "PostalCode":"",
                            "CountryCode":null
                        }
                    },
                    null,
                    null,
                    null
                ],
                "ContactName":{
                    "FirstName":"Bob",
                    "MiddleName":"",
                    "LastName":"Tester"
                }
            }
        }
    }
}

4 个答案:

答案 0 :(得分:1)

经过一点点的讨论后,我想出了一个递归函数,就像我之前建议的那样,将对象转换为数组来检查变量是否设置为null。

如果该对象内的所有变量都为null,则对父对象进行索引,以将对象的引用设置为null。

我试着尽可能地解释和记录代码。

请不要只是复制代码并完成它,但请仔细阅读并尝试从我提供的代码中学习。

/**
    Unsets all empty variables in $object
*/
function loopTrough(&$object, &$parent = null, $key = null, $objectIsArray = false, $parentIsArray = false)
{
    // Keep track of amount of vars and amount of null vars
    $vars = 0;
    $null = 0;
    foreach($object as $index => $value)
    {
        $vars = $vars + 1;

        // Also check if is array
        $isArray = is_array($value);

        // Check if is object
        if (is_object($value) || $isArray) // using value here is save
        {
            // Loop trough the new object (or array) we found
            if ($objectIsArray)
            {
                loopTrough($object[$index], $object, $index, $isArray, $objectIsArray);
            }
            else
            {
                loopTrough($object->{$index}, $object, $index, $isArray, $objectIsArray);
            }
        }

        // Check if is null
        if ($objectIsArray)
        {
            if (!isset($object[$index]) || $object[$index] == ""){
                $null = $null + 1;
                // We don't want to show null
                unset($object[$index]);
            }
        }
        else
        {
            if (!isset($object->{$index}) || $object->{$index} == "") // use $object->{index} here, and not $value because $value does not change when object reference is changed
            {
                $null = $null + 1;
                // We don't want to show null
                unset($object->{$index});
            }
        }
    }

    // If there are as much null variables as variables
    if ($vars == $null && $parent !== null && $key !== null)
    {
        // Set the parent reference to null
        if ($parentIsArray) // Example exludes arrays, uncomment this if you want values in arrays to be recurisvely set to null
        {
            // unset($parent[$key]);
        }
        else
        {
            unset($parent->{$key});
        }   
    }
}



class Test
{
    public $one;

    public $two;
}

$test = new Test();

$test->one = new Test();
$test->one->two = "On";
$test->two = new Test();
$test->two->one = new Test(); 

var_dump($test);

loopTrough($test);

var_dump($test);

答案 1 :(得分:1)

要求:递归扫描嵌套数组,修剪出空的分支/项目。

这是另一个'树木漫步'。

唯一“棘手”的部分是让树上的处理更高知道是否将当前项添加到输出树中。

处理节点的函数将返回一个具有“保持值”标志的数组以及要保留的值。

JSON Converted to array: Full Working code at eval.in

Output preserves original JSON Data Type: Full Working code at eval.in

代码:

function processList(array $list)
{
    $listResult = ['keepValue' => false, // once set true will propagate upward
                    'value'       => []];

    foreach ($list as $name => $item ) {
        if (is_null($item)) { // see is_scalar test
            continue;
        }

        if (is_scalar($item)) { // keep the value?
            if (!empty($item) || strlen(trim($item)) > 0) {
                $listResult['keepValue'] = true;
                $listResult['value'][$name] = $item;
            }

        } else { // new list... recurse

            $itemResult = processList($item);
            if ($itemResult['keepValue']) {
                $listResult['keepValue'] = true;
                $listResult['value'][$name] = $itemResult['value'];
            }
        }
    }   
    return $listResult;
}    

运行功能:

$source = json_decode($json, true);
$result = processList($source);
print_r($result['value']);

输出:

Array
(
    [Supplier] => Array
        (
            [Party] => Array
                (
                    [OrgInfo] => Array
                        (
                            [CompanyName] => Bobs
                            [IDInfo] => Array
                                (
                                    [1] => Array
                                        (
                                            [IDQualifierCode] => CompanyID
                                            [IDNum] => 83e26599-d40g-4cba-9791-7d7c83de282c
                                        )
                                    [2] => Array
                                        (
                                            [IDQualifierCode] => TID
                                            [IDNum] => BOBTID01020304
                                        )
                                    [3] => Array
                                        (
                                            [IDQualifierCode] => Token
                                            [IDNum] => c784570e-044d-42c8-98fe-af9f7c1747f5
                                        )
                                )
                        )
                )
        )
    [Company] => Array
        (
            [Party] => Array
                (
                    [OrgInfo] => Array
                        (
                            [CompanyName] => SF
                        )
                )
        )
    [Facility] => Array
        (
            [Party] => Array
                (
                    [ContactInfo] => Array
                        (
                            [ContactName] => Array
                                (
                                    [FirstName] => Bob
                                    [LastName] => Tester
                                )
                        )
                )
        )
)

答案 2 :(得分:0)

就像我之前建议的那样,您可以将object转换为array并通过元素递归循环以检查它们是否为null

递归函数将变得非常复杂,因为您不想删除空变量,而是删除仅包含null变量的所有内容。

这是一个示例,没有递归,只是从null删除了object个变量:

class A
{
    public $var = "aVar";
    public $var1 = null;
}

$a = new A();

var_dump($a);

$array = (array)$a;

foreach($array as $key => $value)
{
    if (is_null($value)){
        unset($array[$key]);
    }
}

var_dump($array);

答案 3 :(得分:0)

认真没时间测试它,但是编辑:测试过它,原始代码中有一个错误(有clean_iterable(NULL,$v);而不是clean_iterable(NULL,$v[$key]);,修复了它,这似乎有效:

function clean_iterable(Iterable $v=NULL,Iterable &$vv=NULL):Iterable{
    if(isset($vv)){
        $v=&$vv;
    }
    if(empty($v)){
        return $v;
    }
    foreach($v as $key=>$val){
        if(empty($val)){
            unset($v[$key]);
        }elseif(is_iterable($val)){
            clean_iterable(NULL,$v[$key]);
        }
    }
    return $v;
}