2015-02-06 6 views
10

구체적인

먼저 PHP에서 평등의 개체를 비교하여, 내 경우에는 "평등"의 정의는 - 그들이 그 구조와 동일한 구조와 값을 가질 때 오브젝트가 동일한 것을. 그러나 그들은 동일한 인스턴스가 아니거나 속성이 동일한 "순서"(즉, 할당/정의됨에 따라)가 아닐 수도 있습니다. 비슷한 질문이 있으므로 this처럼 -하지만 내 사례를 다루지는 않습니다.

필자는 코드 목적을 테스트하기 위해 PHP의 엔티티를 비교해야합니다. 특히 객체 일 수 있습니다. 그러나 Objects comparison은 "안전하지 않습니다".

$result = $objectX == $objectY; 

를 그리고 객체가 순환 참조가있을 때이 경우에 치명적인 오류가 발생할 수 있습니다 : 당신이 비교하는 것을 상상해보십시오. 그것을위한 간단한 예제는 here을 준비했습니다. 우리가 볼 수 있듯이, PHP는 중첩 된 레벨을 따르려고 시도하고 무한 루프에서 실패합니다. 왜냐하면 본질적으로 객체의 내용은 동일하지만 순환 참조가 있기 때문입니다.

중요 세부 사항 (정렬되지 않은 비교 잊어 경우에도) 객체가 "seralize/때 unserialize"접근 방식에 의존하는 것은 불가능합니다 (폐쇄 등) 직렬화 가능하지 않은 물건을 포함 할 수 있다는 것입니다

현재 접근

코드를 this (여기에 직접 붙여 넣기에는 너무 많이 넣었습니다. 다만, 여기서는 gist입니다.) - 따라서 DFS을 수행하고 순환 참조가있는 상황을 잡습니다. 보시다시피, 그것은 매우 복잡합니다. 그런데 느립니다.

현재 접근법의 또 다른 문제는 객체 안에 배열이있을 때 요소 순서와 비교할 때 어떤 경우에는 괜찮지 않다는 것입니다 (이상적인 경우 - 가능한 경우 순서대로 비교를 전환하기 위해)하지만, 기본적으로 그것을 극복하기 위해 어쨌든 배열을 "정렬"해야 할 것입니다. 그리고 어떻게 해야할지 잘 모릅니다. 다시 말해, 배열 요소의 비교가 안전하지 않기 때문입니다.

그리고, 더 원형 배열 참조는 원인이됩니다 실패 :

$array = ['foo', $object, &$array]; 

질문

이 (더 나은) 다른 수 무엇

이 문제를 해결하기 위해 접근 ? 객체를 직렬화하는 경우도있을 수 있지만 순서가 지정되지 않은 속성 집합으로 인해 나를 실패하게됩니다.

+0

'get_object_vars ($ objectX) == get_object_vars ($ objectY)' – DaveRandom

+0

@DaveRandom 아니요 : 1. 순환 참조 (주 지점); 2. 정렬되지 않은 속성 비교 (또한 중요한 점) –

답변

1

Doctrine \ Common \ Util \ Debug :: export ($ class, $ maxDepth)를 알고 계십니까?

"내보내기"방법은 무한 루프를 방지하고 배열을 반환하여 마녀를 사용하여 diff를 만들 수 있습니다.

특정 깊이를 넘어서 더 이상 진행할 필요가 없으며 을 $ maxDepth와 비교하여 비교의 정확도를 지정할 수 있습니다.

+0

[코드] (http://www.doctrine-project.org/api/common/2.3/source-class-Doctrine.Common.Util.Debug.html # 24-136)이 방법은'$ maxDepth'에 의지하도록 고안되었으며, 설정하지 않으면 실패합니다. "실패"란 어떤 유용한 작업도하지 않고 클래스 이름을 출력한다는 것입니다. –