1

So, how do you compare classes that contain Closure ? It looks like you can't.

class a {
    protected $whatever;
    function __construct() {    
        $this->whatever = function() {};
    }
}

$b = new a();
$c = new a();

var_dump( $b == $c );   //false
  • So is it based on the class? So if you did `$c->var = 1;` should they still be `==` or not? – AbraCadaver Apr 09 '15 at 15:48
  • The easiest may be a custom comparison method: `$b->isEqual($c)`, in which you compare everything that matters for equality and ignore incomparable values. – deceze Apr 09 '15 at 16:11

1 Answers1

1

Well you can't serialize() closures straight on, but you can do a workaround, since serialize() invokes __sleep() when it's serializing objects, so it gives the object to option to clean things up! This what we're doing here:

class a {

    protected $whatever;

    function __construct() {    
        $this->whatever = function() {};
    }

    public function __sleep() {
        $r = [];
        foreach ($this as $k => $v){
            if (!is_array($v) && !is_string($v) && is_callable($v))
                continue;
            $r[] = $k;
        }
        return $r;
    }

}

So now you can use serialize() with md5() to compare your objects like this:

var_dump(md5(serialize($b)) === md5(serialize($c))); 

output:

bool(true)
Rizier123
  • 58,877
  • 16
  • 101
  • 156
  • Yeah, it will work for this specific case. But if you redefine whatever they would still be equal. See question update. – user2398964 Apr 09 '15 at 16:27
  • @user2398964 As I said in the answer it's a workaround that you are still able to serialize an object even if it has a closure in it! By simply removing them. But I don't think there is currently a way how you can compare 2 objects with closures in it – Rizier123 Apr 09 '15 at 16:28