2011-05-06 134 views
12
显示DIFF

我在寻找一个方式给我看不同的属性/值从给定的对象......比较对象的属性和在PHP

$obj1 = new StdClass; $obj1->prop = 1; 
$obj2 = new StdClass; $obj2->prop = 2; 

var_dump(array_diff((array)$obj1, (array)$obj2)); 
//output array(1) { ["prop"]=> int(1) } 

这工作得很好,只要财产是不是对象或数组。

$obj1 = new StdClass; $obj1->prop = array(1,2); 
$obj2 = new StdClass; $obj2->prop = array(1,3); 

var_dump(array_diff((array)$obj1, (array)$obj2)) 
// Output array(0) { } 
// Expected output - array { ["prop"]=> array { [1]=> int(2) } } 

有没有办法摆脱这一点,即使当属性是另一个对象?!

+0

通常你在类的方法解决这个问题,就像一个'等于($对象)'方法。也许你不能修改课程? – 2011-05-06 12:15:53

+1

哦,当比较包含对象的属性时,你如何看待对象是相等的?这是一种递归问题......您可以检查它们的属性是否相等(递归问题...)或者它们是否是相同的实例(比平等更强)。 – 2011-05-06 12:17:20

+1

是您正在测试的确切的一个以上的代码?如果是这样,那么$ obj1和$ obj2的prop是相同的数组(1,2)。技术上确实没有区别。 – dragonjet 2011-05-07 07:37:21

回答

4

类似下面,它迭代通过并执行递归差异是数组中的项目本身就是一个数组可以工作:

德相似的工作和array_diff,但它确实检查,看它是否是数组first(is_array),如果是,则将该键的diff设置为该数组的diff。以递归方式重复。

function recursive_array_diff($a1, $a2) { 
    $r = array(); 
    foreach ($a1 as $k => $v) { 
     if (array_key_exists($k, $a2)) { 
      if (is_array($v)) { 
       $rad = recursive_array_diff($v, $a2[$k]); 
       if (count($rad)) { $r[$k] = $rad; } 
      } else { 
       if ($v != $a2[$k]) { 
        $r[$k] = $v; 
       } 
      } 
     } else { 
      $r[$k] = $v; 
     } 
    } 
    return $r; 
} 

然后,它的工作原理是这样的:

$obj1 = new StdClass; $obj1->prop = array(1,2); 
$obj2 = new StdClass; $obj2->prop = array(1,3); 
print_r(recursive_array_diff((array)$obj1, (array)$obj2)); 

/* Output: 
    Array 
    (
     [prop] => Array 
      (
       [1] => 2 
      ) 
    ) 
*/ 
+0

这几乎是我想要的,它不起作用,如果$ obj-> prop是另一个数组作为属性的对象..但我会保持那作为最佳的答案。 – nfo 2011-05-09 07:06:39

+0

在这种情况下,你可以添加到你的循环的东西,检查是否对象是不是数组,不管你是否可以将其转换为一个数组,并对其运行recursive_array_diff。 – 2011-05-09 12:02:18

+0

类似if(is_array($ v)){...} elseif(is_array((array)$ v){...} else {...} 您可能需要检查cast数组来检查你是不是无意的投射值。让我知道如果你工作的东西:) – 2011-05-09 12:03:53