2015-02-06 18 views
10

Specificheconfrontare gli oggetti sulla parità in PHP

In primo luogo, la definizione di "uguaglianza" nel mio caso è - che gli oggetti sono uguali quando hanno stessa struttura e valori per quella struttura. Tuttavia, potrebbero non essere la stessa istanza o le proprietà potrebbero non essere nello stesso "ordine" (intendo, come sono state assegnate/definite). Ci sono domande simili qui su SO, come this - ma non coprono il mio caso.

Ho bisogno di confrontare entità in PHP a causa di test dei miei scopi di codice - e quelle entità potrebbero essere qualsiasi cosa. In particolare, possono essere oggetti. Objects comparison, tuttavia, non è "sicuro". Immaginate che si sta confrontando:

$result = $objectX == $objectY; 

E questo può portare a errore fatale nel caso in cui gli oggetti hanno riferimenti circolari. Semplice esempio per questo ho preparato here. Come possiamo vedere, PHP cerca di seguire i livelli nidificati e fallisce nel ciclo infinito - perché per natura gli oggetti sono uguali nel contenuto, ma hanno riferimenti circolari.

dettaglio importante è che gli oggetti potrebbero contenere materiale non serializzabile (come chiusure), il che rende impossibile fare affidamento su un approccio "seralize/unserialize" (anche se di dimenticare il confronto non ordinata)

approccio attuale

Ho il codice come this (un po 'troppo da incollare direttamente qui, ma nel caso, ecco un gist) - quindi sto eseguendo DFS lì e prendendo situazioni con tali riferimenti circolari. Come puoi vedere, è piuttosto complesso e, a proposito, è lento.

Un altro problema con l'approccio attuale è che quando ci sono matrici all'interno di oggetti, saranno confrontati con il rispetto dell'ordine di elementi, il che, in alcuni casi, non mi va bene (caso ideale - quando sarò in grado per passare al confronto ordine-saggio), ma per superarlo in modo nativo, probabilmente avrò bisogno di "ordinare" gli array in qualche modo - e non ho idea di come farlo - poiché, ancora una volta, il confronto di quegli array non sarà sicuro.

e, più, circolari array riferimenti anche causare il guasto:

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

Domanda

Che cosa potrebbe essere altro (meglio) approcci per risolvere una questione? La serializzazione degli oggetti potrebbe essere il caso, ma a causa di un insieme non ordinato di proprietà non funzionerà per me.

+0

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

+0

@DaveRandom no, perché: 1. Riferimenti circolari (punto principale); 2. Confronto delle proprietà non ordinate (anche punto importante) –

risposta

1

Conosci Doctrine \ Common \ Util \ Debug :: export ($ class, $ maxDepth)?

Questo metodo "esporta" impedisce il loop infinito e restituisce una matrice che può essere utilizzata per rendere diff.

Oltre una certa profondità, non è necessario andare oltre e con $ maxDepth è possibile specificare la "precisione" del confronto.

+0

Guardando al [codice] (http://www.doctrine-project.org/api/common/2.3/source-class-Doctrine.Common.Util.Debug.html # 24-136) Vedo che questo metodo è progettato per fare affidamento su '$ maxDepth' e fallirà se non fosse impostato. Con "fail" intendo che non farà alcun lavoro utile, basta stampare il nome della classe e basta. –