未能递归筛选多维对象数组


Failing to recursively filter multidimensional array of objects

我有一个变量,它可能是对象或数组。如果它是一个数组,那么它将由对象组成。每个对象可以具有一个参数,该参数是另一个对象或对象阵列。所有阵列都可以是n级深。

所有对象都有一个参数"isAccessible"。此参数的值可能为true或false。

如果为false,则必须从结构中删除该对象。

我尝试过array_filter,因为我不能像描述的那样递归过滤,所以我写了一个homerolled递归函数。

然而,我一直没能让它发挥作用。这是我的代码:

public static function jsonGateway($json) {
    $object = json_decode($json);
    $newJSON = '';
    // $object may be a stdClass Object or it may be an array of stdClass Objects
    // An objects parameters may be a string, integer, or an array of stdClass Objects.
    // This function must recurse arbitrarily deep
    // Any object where isAccessible = 0 must be purged (numeric string or int?)
    if (is_object($object)) {
        if ($object->isAccessible == 1 || $object->isAccessible == '1' || $object->isAccessible == true) {
            $newJSON = $json;
        }
    } else if (is_array($object)) {
        $newJSON = json_encode(self::filterRecursive($object));
    }
    echo $newJSON;
}
public static function filterRecursive(Array $source) {
    $result = array();
    foreach ($source as $key => $value) {
        if (is_object($value)) {
            $object = $value; // Just a comprehension aid
            if ($object->isAccessible == 1 || $object->isAccessible == '1' || $object->isAccessible == true) {
                // Keep this object
                // This objec though, may have a parameter which is an array
                // If so, we need to recurse
                $objectVars = get_object_vars($object);
                if (count($objectVars) > 0) {
                    foreach ($objectVars as $objectParameter => $objectValue) {
                        if (is_object($objectValue)) {
                            if ($object->isAccessible == 1 || $object->isAccessible == '1' || $object->isAccessible == true) {
                                $object[$objectParameter] = $objectValue;
                            }
                        } else if (is_array($objectValue)) {
                            $object[$objectParameter] = self::filterRecursive($objectValue); // Line 177
                        }
                    }
                }
                $result[$key] = $object;
            } else {
                // don't need this block
                error_log("deleting: " . print_r($object,true));
            }
        }
        if (is_array($value)) {
            $array = $value; // Just a comprehension aid
            $result[$key] = self::FilterRecursive($array);
            continue;
        }
    }
    return $result;
}

我不仅没有成功过滤任何东西,我得到了以下错误:

PHP Fatal error:  Cannot use object of type stdClass as array in /home1/lowens/public_html/dev/classes/Lifestyle/RBAC.php on line 177

你能帮忙吗?

解决方案:

/**
 * @param array $array
 * @return array
 */
public static function filterArray(Array $array) {
    $result = array();
    foreach ($array as $key => $value) {
        if (is_object($value)) {
            $newObject = self::filterObject($value);
            if (count(get_object_vars($newObject)) > 0) {
                $result[$key] = $newObject;
            }
        } else if (is_array($value)) {
            $newArray = self::filterArray($value);
            if (count($newArray) > 0) {
                $result[$key] = $newArray;
            }
        } else {
            $result[$key] = $value;
        }
    }
    return $result;
}
/**
 * @param 'stdClass $object
 * @return 'stdClass
 */
public static function filterObject('stdClass $object) {
    $newObject = new 'stdClass();
    if ($object->isAccessible == 1) {
        $objectVars = get_object_vars($object);
        foreach ($objectVars as $objectParameter => $objectValue) {
            if (is_object($objectValue)) {
                $newObject->$objectParameter = self::filterObject($objectValue);
            } else if (is_array($objectValue)) {
                $newObject->$objectParameter = self::filterArray($objectValue);
            } else {
                $newObject->$objectParameter = $objectValue;
            }
        }
    }
    return $newObject;
}