private static function subtreeEquals($a, $b)
    {
        if (gettype($a) !== gettype($b)) {
            return false;
        }

        if (is_scalar($a)) {
            return ($a === $b);
        }

        if (is_array($a)) {
            $len = count($a);

            if ($len !== count($b)) {
                return false;
            }

            // TODO Ignore order for sets?
            for ($i = 0; $i < $len; $i++) {
                if (false === self::subtreeEquals($a[$i], $b[$i])) {
                    return false;
                }
            }

            return true;
        }

        if (!property_exists($a, '@id') &&
            !property_exists($a, '@value') &&
            !property_exists($a, '@list')) {
            // Blank nodes can never match as they can't be identified
            return false;
        }

        $properties = array_keys(get_object_vars($a));

        if (count($properties) !== count(get_object_vars($b))) {
            return false;
        }

        foreach ($properties as $property) {
            if ((false === property_exists($b, $property)) ||
                (false === self::subtreeEquals($a->{$property}, $b->{$property}))) {
                return false;
            }
        }

        return true;
    }
private static function subtreeEquals($a, $b)
    {
        if (gettype($a) !== gettype($b)) {
            return false;
        }

        if (is_scalar($a)) {
            return ($a === $b);
        }

        if (is_array($a)) {
            $len = count($a);

            if ($len !== count($b)) {
                return false;
            }

            // TODO Ignore order for sets?
            for ($i = 0; $i < $len; $i++) {
                if (false === self::subtreeEquals($a[$i], $b[$i])) {
                    return false;
                }
            }

            return true;
        }

        if (!property_exists($a, '@id') &&
            !property_exists($a, '@value') &&
            !property_exists($a, '@list')) {
            // Blank nodes can never match as they can't be identified
            return false;
        }

        $properties = array_keys(get_object_vars($a));

        if (count($properties) !== count(get_object_vars($b))) {
            return false;
        }

        foreach ($properties as $property) {
            if ((false === property_exists($b, $property)) ||
                (false === self::subtreeEquals($a->{$property}, $b->{$property}))) {
                return false;
            }
        }

        return true;
    }
private static function subtreeEquals ( $ a , $ b ) { if ( gettype ( $ a ) !== gettype ( $ b ) ) { return false ; } if ( is_scalar ( $ a ) ) { return ( $ a === $ b ) ; } if ( is_array ( $ a ) ) { $ len = count ( $ a ) ; if ( $ len !== count ( $ b ) ) { return false ; } // TODO Ignore order for sets? for ( $ i = 0 ; $ i < $ len ; $ i ++ ) { if ( false === self :: subtreeEquals ( $ a [ $ i ] , $ b [ $ i ] ) ) { return false ; } } return true ; } if ( ! property_exists ( $ a , '@id' ) && ! property_exists ( $ a , '@value' ) && ! property_exists ( $ a , '@list' ) ) { // Blank nodes can never match as they can't be identified return false ; } $ properties = array_keys ( get_object_vars ( $ a ) ) ; if ( count ( $ properties ) !== count ( get_object_vars ( $ b ) ) ) { return false ; } foreach ( $ properties as $ property ) { if ( ( false === property_exists ( $ b , $ property ) ) || ( false === self :: subtreeEquals ( $ a -> { $ property } , $ b -> { $ property } ) ) ) { return false ; } } return true ; }
Verifies whether two JSON-LD subtrees are equal not

Please note that two unlabeled blank nodes will never be equal by
definition.

@param mixed $a The first subtree.
@param mixed $b The second subree.

@return bool Returns true if the two subtrees are equal; otherwise
false.
Verifies whether two JSON - LD subtrees are equal not