9

In a PHP program I have an array of some custom objects, and I want to find if the array contains a certain object. Of course I can use array_search, but this checks if the objects are the same object, not if it has the same variables. So I want to be able to create my own compare function for the objects, which I can use with the array_search method (or something similar). I want to be able to do something like this:

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

Is something like this possible? I know I can also create my own array_search method which uses a method from the class, but than I'd have to use 2 different search functions, one for the classes which do have their own compare function, and one for those which haven't.

Tiddo
  • 6,331
  • 6
  • 52
  • 85
  • 2
    array_search only checks if the objects are the same instance if you set its third $strict parameter to true. Otherwise, two objects are considered equal if they "have the same attributes and values, and are instances of the same class" - see the behavior of the [==](http://php.net/manual/en/language.oop5.object-comparison.php) operator. – yscik Feb 09 '11 at 16:32

2 Answers2

8

Here's a neat little trick I recently found out:

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

This also works:

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

When passed a string $needle, array_search will try to cast the objects contained in $haystack to string to compare them, by calling the __toString magic method if it exists, which in this case returns Foo::$a.

netcoder
  • 66,435
  • 19
  • 125
  • 142
  • That is very helpful. As long as you're comparing an object to a string, PHP will coerce it to a string value using its `__toString` method. – David Harkness May 24 '13 at 23:55
3

Usually its not. You may look at the PECL Operators-Extension, but thats really old.

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • 2
    It's been updated now for 5.3 *and* 5.4, but a package that goes 7 years between releases doesn't exactly inspire trust in its maintenance... – Xiong Chiamiov May 17 '13 at 18:40
  • 1
    @XiongChiamiov Depends. If it works, there is no need for an update, is it? – KingCrunch May 18 '13 at 01:00
  • 1
    Furthermore, it's still in beta state. You should consider that if you're planning to use it in a production environment. – Arne L. Nov 09 '15 at 11:20