1

Finishing up an open source Domain Registrar plugin and having a few troubles with determining when a change has been made.

$saved = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '8.8.8.8' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' )
    );

$new = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' ),
        array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
    );

$saved is the values already saved at the domain registrar, and is only being used for comparison.

$new is the array returned from application that processed the form on the website.

I need to somehow only return arrays that have values that were updated or that do not already exist/match from $saved.

Basically the return array i'm looking for would be:

array(
    array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' )
    array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
);

Because in $saved the value was updated from 8.8.8.8 to 4.4.4.4, and the sub.mydomain.com did not match any array from $saved meaning it's a new entry.

Using array_intersect I was able to get it to return the array that had it's values updated, but unfortunately it still includes the arrays that matched as well. If I could somehow have those removed that would be exactly what I need.

Here's a demo: http://glot.io/php/529b0c6d2fd16fe221f86bb521155384

Maybe use array_uintersect with a callback to check if the arrays match and unset? Looking for some help as i'm stuck on this now.

Thanks!!

  • What about $diff = array_diff($new, array_intersect($new, $saved));? – Jimmy Sawczuk Sep 23 '14 at 2:04
1

Well in this case you could flatten them thru serializing, them map, them finally array_dif()

$result = array_map('unserialize', array_diff(array_map('serialize', $new), array_map('serialize', $saved)));

Should produce based on example:

Array
(
    [0] => Array
        (
            [domain] => mydomain.com
            [record] => A
            [value] => 4.4.4.4
        )

    [2] => Array
        (
            [domain] => sub.mydomain.com
            [record] => A
            [value] => 1.2.3.4
        )

)
  • Perfect! Works just like needed and simple without adding function! Thanks!! – sMyles Sep 23 '14 at 14:53
1

array_udiff should work here.

Something along the lines of the following comparison function as a custom callback should do the trick:

$saved = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '8.8.8.8' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' )
    );

$new = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' ),
        array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
    );


function cmpr($a, $b) {
    foreach($a as $k=>$v) {
        if ($b[$k] !== $v)
            return -1;
    }
    return 0;
}

var_dump(array_udiff($new, $saved, 'cmpr'));

The output should look something like what you expected:

array(2) {
  [0]=>
  array(3) {
    ["domain"]=>
    string(12) "mydomain.com"
    ["record"]=>
    string(1) "A"
    ["value"]=>
    string(7) "4.4.4.4"
  }
  [2]=>
  array(3) {
    ["domain"]=>
    string(16) "sub.mydomain.com"
    ["record"]=>
    string(1) "A"
    ["value"]=>
    string(7) "1.2.3.4"
  }
}
  • Thank you for your response, this does in fact work, but i'm going to use the serialize one to keep it simple and without adding another function. Thank you for your help though, greatly appreciated and your solution does work! – sMyles Sep 23 '14 at 14:52
  • Sure, no problem. Though you should probably know that the PHP serializer is really slow. This doesn't simplify your problem it sort of complicates a bit actually. Also, you can use a closure if you don't want the function defined in the global scope. – Sherif Sep 23 '14 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.