如何在PHP中比较两个数组和列表差异?

时间:2009-02-02 19:50:20

标签: php arrays

我正在构建一个表单来执行以下操作:

  • 打印一个用户和权限表,从MySQL中提取。用户拥有的每个权限都是一个复选框,他们缺少的每个权限都是未经检查的框。
  • 允许管理员选中和取消选中要授予或删除权限的复选框。
  • 提交表单后,只显示一个确认页面,其中只包含权限将被更改的用户,突出显示具体更改。
  • 确认更改后,相应地修改数据库。

为此,我创建了两个用户权限数组:一个根据数据库显示的内容,另一个根据表单显示的内容。

如果用户在MySQL中缺少权限,则会显示为0.如果他们在表单提交中缺少权限,则根本不存在。

以下是两个简单的数组示例:

数据库数组

[User1] => Array ([public] => 1
                [private] => 1
                [secret] => 1
               ) 
[User2] => Array ([public] => 1
                [private] => 0
                [secret] => 0
               )

表单提交数组(从User1撤销“secret”并将其提供给User2)

[User1] => Array ([public] => 1
                [private] => 1 
               )

[User2] => Array ([public] => 1
                  [secret] => 1
                 )

问题

我如何优雅地组合这两个数组来制作一个“更改”数组,以便:

  • 省略两者具有相同权限的用户
  • 剩余用户将所有权限(public,private和secret)设置为0或1。
  • 如果表单提交数组中缺少每个权限,则为0;如果表单提交数组中有,则为1;

例如,结合上述内容可以得到:

[User1] => Array ([public] => 1
                [private] => 1
                [secret] => 0
               ) 
[User2] => Array ([public] => 1
                [private] => 0
                [secret] => 1
               )

到目前为止的尝试

  • 作为第一步,我尝试使用array_merge(),其中第二个列出了表单数组,认为它会覆盖它们不同的数据库数组。相反,它删除了不同的元素。
  • 我已经尝试设置foreach()语句来比较两个数组,但它变得复杂了,我认为必须有一个更简单的方法

更新

呼!一个新的答案引起了我对这个老问题的关注。我得到了这个工作,但后来我废弃了这个疯狂的代码 - 它太复杂了回去工作。相反,我编写了一个PHP后端脚本来一次更改一个权限,然后写了一个AJAX前端来发送更改。更简单的代码,并且对用户的更改是即时的。突出显示效果可以即时提供有关更改内容的页面反馈。

6 个答案:

答案 0 :(得分:2)

这可能是您正在寻找的: array_diff()

答案 1 :(得分:2)

您可以参考PHP: Arrays manual找到所需内容。你已经很好地记录了这个问题,但我仍然无法清楚地知道你需要什么。

具体来说,您应该考虑使用array_diff()和array_intersect()来计算两个数组的差异或交集。

答案 2 :(得分:2)

帖子数据仅包含您应授予的权限。因此,设置一个“基线”,将所有权限设置为0.然后与提交合并。

$empty_perms = array("public" => 0, "private" => 0, "secret" => 0);

$new_user1_perms = array_merge($empty_perms, $_POST['User1']);
$new_user2_perms = array_merge($empty_perms, $_POST['User2']);

现在使用合并的数组更新数据库。这样,您将为所有元素设置正确的权限。

答案 3 :(得分:1)

让我们尝试将gnud的解决方案与按价值进行比较。 我添加了一个关键的“成员”来显示零权限不变。

// empty permissions
$empty_perms = array("public" => 0, "private" => 0, "secret" => 0, "member" => 0);

// original permissions (please note that it MUST contain ALL keys)
$old_perms = array("public" => 1, "private" => 0, "secret" => 1, "member" => 0);

// POST data container
$post_data = array("public" => 1, "private" => 1);

// apply new user permissions - put them into db
$new_perms = array_merge($empty_perms, $post_data);

// differences to show
$diff_perms = array();

// compare new and old permissions
foreach($empty_perms as $k => $v) {
    $diff_perms[$k] = (int)($old_perms[$k] !== $new_perms[$k]);
}

此示例应该为您提供以下结果(旧的,新的,更改):

Array
(
    [public] => 1
    [private] => 0
    [secret] => 1
    [member] => 0
)

Array
(
    [public] => 1
    [private] => 1
    [secret] => 0
    [member] => 0
)

Array
(
    [public] => 0
    [private] => 1
    [secret] => 1
    [member] => 0
)

希望这有帮助。

答案 4 :(得分:0)

我想知道differential execution上的某种变体是否会有所帮助。

答案 5 :(得分:0)

要使用array_diff(),第一个参数必须是超集,或两个数组中较大的一个。当您不确定哪个数组更大时使用array_diff()

  //start with the superset of for array_diff to return differences
  if(count($prev_wholesaler_assignments) > count($wholesalers)){
      $perm_diff = array_diff($prev_wholesaler_assignments,$wholesalers);  
  } elseif (count($prev_wholesaler_assignments) < count($wholesalers)){
      $perm_diff = array_diff($wholesalers,$prev_wholesaler_assignments);
  }

无论哪个数组碰巧变大,都会返回析取。