2014-07-08 2 views
1

두 개체 스키마가 동일한 지 (php에서) 동적으로 확인할 수 있습니까? 예 :PHP 개체 스키마 유효성 검사

{ 
    name: "Name1", 
    age: 2, 
    kids: [1,3,4] 
} 

{ 
    name: "Name2", 
    age: 2, 
    kids: [1,6,4,3] 
} 

위의 예에서 나는 사실을 반환 할 것으로 기대하고 있습니다. 다른 예가 있습니다 :

{ 
    name: "Name1", 
    age: 2, 
    kids: [1,3,4] 
} 

{ 
    name: "Name1", 
    kids: [1,3,4] 
} 

여기서 나는 틀린 (스키마가 같지 않습니다 : 두 번째 객체에서 누락 된 나이) 것을 기대합니다.

함수 정의는 다음과 같아야합니다. Boolean isSchemaEqual($obj1, $obj2) (PHP에 함수 정의가 없다는 것을 알고 있습니다. 제 질문을 더 명확히하기 위해서였습니다).

참고 : 스키마는 중첩 될 수 있습니다. 즉, 일부 속성은 다른 개체의 (동일한) 속성에 대해 검사해야하는 개체를 보유 할 수 있습니다.

답변

1

: 한 가지 방법은 {kids: {boys: [1,2,3]}}kids/boys되고 같은 경로로, 그것을 하나의 레벨을하는 것입니다, 당신은 배열을 비교할 수 있습니다 키에 대한 순서가없는 배열 비교 관용구가 있습니다.

// determines if an array is associative 
function isAssociative($array) { 
    return (bool)count(array_filter(array_keys($array), 'is_string')); 
} 

// determines if the keys of two arrays are equal regardless of order 
function keysEqual($a, $b) { 
    if (!is_array($a) || !is_array($b)) 
     return false; 

    $keysA = array_keys($a); 
    $keysB = array_keys($b); 

    return array_diff($keysA, $keysB) === array_diff($keysB, $keysA); 
} 

function isSchemaEqual($a, $b) { 
    // validate keys - basic validation 
    if (!keysEqual($a, $b)) 
     return false; 

    // if we come across any key where the value is associative and 
    // the schema isn't the same for b's value at $key, then we know 
    // the schemas aren't equal 
    foreach ($a as $key => $value) { 
     if (is_array($value) && isAssociative($value) && !isSchemaEqual($value, $b[$key])) 
      return false; 
    } 

    // we couldn't find any differences, so they're equal 
    return true; 
} 

당신은 몇 가지 테스트를 찾을 수 here.

0

은 키 비교 :

if (array_keys($schema1) == array_keys($schema2)) { 

} 

중첩 된 개체를 들어, 당신은 당신의 자신의 기능을해야 할 것이다. 당신이 스키마의 여러 ​​수준을 검증하기 위해 찾고 있다면 당신이 함께 재귀를 사용할 수

function flatten_keys($object, $prefix = '') { 
    $result = array(); 
    foreach ($object as $key=>$value) { 
    $result[] = $prefix . $key; 
    if (is_object($value) || (is_array($value) && array_values($value) != $value)) { 
     $result = array_merge($result, flatten_keys($value, $key .'/')); 
    } 
    } 
    return $result; 
} 

$a = flatten_keys($schema2); 
$b = flatten_keys($schema2); 
sort($a); 
sort($b); 
if ($a == $b){ 

} 
+0

schema1 & schema2는 예와 같은 개체입니까? – vlio20

+2

이것은 좋은 해결책이지만, @ vlio20이 여러 레벨의 유효성을 검사하려고한다고 가정 할 때 첫 번째 레벨의 키에 대해서만 작동합니다. 또한 키가 같은 순서가 아닌 경우 실패합니다. –

+0

@ vilo20 예 업데이트 –