2011-02-09 11 views
9

In un programma PHP ho una matrice di alcuni oggetti personalizzati, e voglio scoprire se l'array contiene un certo oggetto. Certo che posso usare array_search, ma questo controlla se gli oggetti sono lo stesso oggetto, non se ha le stesse variabili. Quindi voglio essere in grado di creare la mia funzione di confronto per gli oggetti, che posso usare con il metodo array_search (o qualcosa di simile). Voglio essere in grado di fare qualcosa del genere:overload php equals-operator

class foo 
{ 
    public $_a,$_b; 
    function __construct($a,$b) 
    { 
     $this->_a = $a; 
     $this->_b = $b; 
    } 

    function __equals($object) 
    { 
     return $this->_a == $object->_a; 
    } 
} 
$f1 = new foo(5,4); 
$f2 = new foo(4,6); 
$f3 = new foo(4,5); 

$array = array($f1,$f2); 
$idx = array_search($f3,$array); // return 0 

è qualcosa di simile possibile? So che posso anche creare il mio metodo array_search che utilizza un metodo dalla classe, ma dovrei usare 2 diverse funzioni di ricerca, una per le classi che hanno la loro funzione di confronto e una per quelle che hanno 't.

+2

array_search controlla solo se gli oggetti sono la stessa istanza se si imposta il suo terzo parametro $ strict su true. Altrimenti, due oggetti sono considerati uguali se "hanno gli stessi attributi e valori e sono istanze della stessa classe" - vedi il comportamento di [==] (http://php.net/manual/en/language. oop5.object-comparison.php) dell'operatore. – yscik

risposta

8

Ecco un piccolo trucco pulito di recente ho scoperto:

class Foo { 
    public $a; 
    public $b; 

    public function __toString() { 
     return (string)$this->a; 
    } 

    public function __construct($a, $b) { 
     $this->a = $a; 
     $this->b = $b; 
    } 

} 

$a = new Foo(1, 'a'); 
$b = new Foo(2, 'b'); 
$c = new Foo(3, 'c'); 
$d = new Foo(2, 'd'); 
$array = array($a, $b); 

$key = array_search($d, $array);   // false 

$key = array_search((string)$c, $array); // false 
$key = array_search((string)$d, $array); // 1 

questo funziona anche:

$is_equal = ((string)$d == $b);   // true 

Quando viene passato una stringa $ ago, array_search cercherà di lanciare gli oggetti contenuti nel $ pagliaio $ a stringa per confrontarli, chiamando il metodo magico __toString se esiste, che in questo caso restituisce Foo::$a.

+1

Grazie! quello era davvero un bel trucco! – Tiddo

+0

Questo è molto utile. Finché stai confrontando un oggetto con una stringa, PHP lo costringerà a un valore stringa usando il suo metodo '__toString'. –

3

Di solito non è. Si può guardare il PECL Operators -Estensione, ma questo è veramente vecchio.

+2

È stato aggiornato ora per 5.3 * e * 5.4, ma un pacchetto che va 7 anni tra le versioni non ispira esattamente la fiducia nella sua manutenzione ... –

+1

@XiongChiamiov Depends. Se funziona, non è necessario un aggiornamento, vero? – KingCrunch

+1

Inoltre, è ancora in stato beta. Dovresti considerare questo se hai intenzione di usarlo in un ambiente di produzione. –