巨型elseif链,巨型开关或具有功能的微型开关?

时间:2011-02-21 16:18:18

标签: php navigation structure

我有一个9000行的PHP文件,它由大约30个离散区域组成,导航到$_POST个变量。所以可能是......

elseif (isset($_POST['view_user']) 
     || isset($_POST['edit_user']) 
     || isset($_POST['process_user_status']))

......等等。我可能有大约75个进入这三十个区域的点,所有这些都是由像上面这样长的elseif isset链处理。

我一直在考虑将其改为更加理智的东西。到目前为止我提出的想法:

1)将帖子简化为布尔值,并在elseif链中使用它。因此,如果设置了上述elseif ($area_user)中的任何$area_user,则上述内容将归结为true$_POST设置为case (isset($_POST['view_user'])): case (isset($_POST['edit_user'])): case (isset($_POST['process_user_status'])): do stuff; break; 。但这并没有真正解决复杂性问题。

2)用例而不是elseif。所以上面会变成......

UserArea($_POST['whatever'])

但是,同样,虽然它删除了elseif语法,但它只是用一些东西替换它,虽然稍微易于管理,但仍可能隐藏真正的问题。

3)使用功能。所以在页面的顶部,我有一个类似的switch语句,但它没有直接进入脚本区域,而是直接进入脚本区域,它调用了一个函数,所以代替'do stuff'它可能会调用{{ 1}}。这样做的好处是可以将所有$_POST变量移到脚本之外,并将它们集中到导航和函数调用中。但是,它需要许多全局函数声明,目前我不需要这样做,因为elseif的分支在全局范围内。

4)完全使用完整的MVC分割,模板等进行重构。此时此刻非常喜欢但不是一个选项。只是高兴我将模型拆分,但视图和控制器现在必须共存。

正如我写这篇文章一样,我越来越多地说服自己3,但我想看看你们所有人的想法。对于这种情况,最佳实践导航应该是什么?

1 个答案:

答案 0 :(得分:2)

还有一个选项:处理函数字典。

将所有潜在 $ _POST键('view_user'等)放在一个关联数组中,指向处理它们的函数(名称)。然后,代替你的ifelse链,遍历实际的 $ _POST键,直到你在数组中找到匹配并调用相关的函数。

现在您可以将处理程序函数移动到其他文件中而不会感到痛苦,但您可能需要向该动态函数调用添加一些参数。大多数MVC框架都使用这种调度(针对路径中的模式,而不是形式或查询字符串数据)。

// Untested, but something like this
$handlers = array(
  'view_user' => 'UserArea',
  'edit_user' => 'UserArea',
  'view_document' => 'DocManagement', // for example
  // etc...
);
foreach ($_POST as $key => $value) {
  if(array_key_exists($key, $handlers)){
    call_user_func($handlers[$key]);
  }
}