2014-09-23 86 views
1

完成一个开源的Domain Registrar插件并且在确定何时进行更改时遇到一些麻烦。PHP比较两个数组并仅返回唯一的数组值

$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是已经保存在域注册商的值,并且只被用于比较。

$new是从处理网站上的表单的应用程序返回的数组。

我需要以某种方式只返回值已更新或不存在/从$saved匹配的数组。

基本上返回数组我要找的是:

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

由于$savedvalue8.8.8.8更新到4.4.4.4sub.mydomain.com没有从$saved这意味着它是一个新的条目匹配任何数组。

使用array_intersect我能够得到它返回的数组已更新值,但不幸的是它仍然包含匹配的数组。如果我能以某种方式删除那些正是我需要的东西。

这里有一个演示: http://glot.io/php/529b0c6d2fd16fe221f86bb521155384

也许使用array_uintersect有一个回调,以检查是否匹配阵列和取消?寻找一些帮助,因为我现在卡住了。

谢谢!

+0

什么'$差异= array_diff($ new,array_intersect($ new,$ saved));'? – 2014-09-23 02:04:57

回答

1

那么在这种情况下,你终于可以展平,然后直通序列化,并将它们映射,他们array_dif()

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

应该产生基于例如:

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 
     ) 

) 
+0

完美!像需要和简单工作,无需添加功能!谢谢!! – sMyles 2014-09-23 14:53:23

+0

@Myles确定男人很高兴这有帮助 – Ghost 2014-09-23 14:54:01

1

array_udiff应该在这里工作。

东西沿着以下比较功能作为一个自定义回调线应该做的伎俩:

$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')); 

输出看起来应该像你所期望的:

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" 
    } 
} 
+0

谢谢你的回应,这确实有效,但我将使用序列化的一个来保持它简单,并且不添加其他功能。尽管感谢您的帮助,但非常感谢您的解决方案! – sMyles 2014-09-23 14:52:59

+0

当然,没问题。尽管您应该知道PHP串行器非常慢。这并不能简化你的问题,实际上它有点复杂。另外,如果您不想在全局范围中定义函数,则可以使用闭包。 – Sherif 2014-09-23 21:56:25