2011-02-09 25 views
9

En un programa PHP tengo una matriz de algunos objetos personalizados, y quiero encontrar si la matriz contiene un determinado objeto. Por supuesto, puedo usar array_search, pero esto comprueba si los objetos son el mismo objeto, no si tiene las mismas variables. Así que quiero poder crear mi propia función de comparación para los objetos, que puedo usar con el método array_search (o algo similar). Quiero ser capaz de hacer algo como esto:sobrecarga de php igual-operador

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 

es algo como esto posible? Sé que también puedo crear mi propio método array_search que utiliza un método de la clase, pero que tendría que usar 2 funciones de búsqueda diferentes, una para las clases que tienen su propia función de comparación, y otra para las que no tienen acceso 't.

+2

array_search solo comprueba si los objetos son la misma instancia si establece su tercer parámetro $ strict en verdadero. De lo contrario, dos objetos se consideran iguales si "tienen los mismos atributos y valores, y son instancias de la misma clase": vea el comportamiento de [==] (http://php.net/manual/en/language. operador oop5.object-comparison.php). – yscik

Respuesta

8

Aquí hay un pequeño truco recientemente descubrí:

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 

Esto también funciona:

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

Cuando se transmite un $ string aguja , array_search tratará de emitir los objetos contenidos en $ haystack en una cadena para compararlos, llamando al método __toString magic si existe, que en este caso devuelve Foo::$a.

+1

Gracias! ¡fue un truco muy bueno! – Tiddo

+0

Eso es muy útil. Siempre que compares un objeto con una cadena, PHP lo forzará a un valor de cadena utilizando su método '__toString'. –

3

Normalmente no es así. Puede mirar el PECL Operators -Extensión, pero eso es muy viejo.

+2

Se ha actualizado ahora para 5.3 * y * 5.4, pero un paquete que dura 7 años entre versiones no inspira confianza en su mantenimiento ... –

+1

@ XiongChiamiov Depende. Si funciona, no hay necesidad de una actualización, ¿o sí? – KingCrunch

+1

Además, todavía está en estado beta. Debe considerar eso si planea usarlo en un entorno de producción. –