0

I need to check if an array of DOMNode objects contains all the items in a similar array of DOMNode objects.

In general, to check if an array contains another array, I've tried some of the methods outlined in this question. However, both array_intersect() and array_diff() compare array items on the bases (string) $elem1 === (string) $elem2 - which throws the following error for DOMElements as they can't be converted to strings.

PHP Catchable fatal error: 
Object of class DOMElement could not be converted to string in...

What would be the proper way of handling this?

Community
  • 1
  • 1
Chris
  • 5,882
  • 2
  • 32
  • 57
  • String casting should not be done for object compare. Just simple compare to verify object equality. See http://stackoverflow.com/questions/11172506/comparing-a-dom-node-wih-a-dom-element – kuldeep.kamboj May 09 '14 at 13:37
  • Do you want to know if both arrays are identical with the same DOMNodes or just a difference or a true or false, if array A contains the same nodes as array B? – Timmetje May 09 '14 at 13:40
  • @TimDev - I'm looking to find true/false if ArrayA contains everything in ArrayB. – Chris May 09 '14 at 13:41
  • @kuldeep.kamboj - Sure, I understand that. But unfortunately that's how the `array_intersect()` and `array_diff()` methods work. I could of course manually loop everything, but I thought php may have a more efficient solution. – Chris May 09 '14 at 13:42
  • 1
    You'll need to create your own method, there's no other diff method to do this with. – Timmetje May 09 '14 at 13:43
  • @TimDev - Ah shucks. Thought there would be something when there were so many different ways to solve the problem if they were basic types. I'll scrawl something up and post it back here...cheers. – Chris May 09 '14 at 13:45
  • 1
    If you want to know if they are exactly the same you could serialize the arrays and simply compare. But that's not what you need. But you can serialize each item you loop in your method! Good luck! – Timmetje May 09 '14 at 13:48

2 Answers2

1

I've made this which seems to work, as example i filled both arrays with all kinds of objects and types just to see if it works:

$array = array(new DOMDocument(), 'foobar', 112312, new DateTime('Y'));
$array2 = array(new DOMDocument(), 'foobar',12312, false, new DateTime('Y'), 112312, true);

var_dump(array_diff_two($array,$array2)); //returns true

$array = array(new DOMDocument(), 'foobar', 112312, new DateTime('m'));
$array2 = array(new DOMDocument(), 'lorem ipsum!',12312, false, new DateTime('Y'), 112312, true);

var_dump(array_diff_two($array,$array2)); //returns false

function array_diff_two($array1, $array2){
    // serialize all values from array 2 which we will check if they contain values from array 1
    $serialized2 = array();
    foreach ($array2 as $value){
        $serialized2[] = serialize($value);
    }

    // Check if all values from array 1 are in 2, return false if it's not found
    foreach ($array1 as $value) {
        if (! in_array(serialize($value), $serialized2)) {
            return false;
        }
    }
    return true;
}
Timmetje
  • 7,641
  • 18
  • 36
1

As I've written it now, here's an alternative solution. Tim's solution is more readable, in my opinion.

//Does array of DOMNodes contain other array DOMNodes
private function array_contains_array($haystack,$needle){
    //Create object hash array of $haystack
    $haystackHashArr = array();
    foreach ($haystack as $idx => $haystackObj) {
        $haystackHashArr[$idx] = spl_object_hash($haystackObj);
    }

    //Now search for hashes of needle array objects in Haystack-hash-Array
    foreach ($needle as $domNode) {
        $huntedForHash = spl_object_hash($domNode);
        foreach($haystackHashArr as $hsHash){
            if ($hsHash == $huntedForHash) continue 2;
        }
        //Only get here if an item not found (Due to continue statement)
        return false;
    }
    return true;
}
Community
  • 1
  • 1
Chris
  • 5,882
  • 2
  • 32
  • 57