如何将$_POST/$_GET处理代码与html表单/urls解耦?(PHP-OOP)


How can I decouple $_POST/$_GET handling code from html forms/urls? (PHP-OOP)

在一个类中,我有一个处理方法,它根据可用的post/get变量执行操作。下面是一个简化的例子:

public function handleAll(array $vars) {
    if (isset($vars['var1'])) {
        $this->doThisAction($vars['var1']);
    } else if (isset($vars['var2'])) {
        $this->doAnotherAction($vars['var2']);
    }
}

因此,在运行时,可以像这样调用该方法$handler->handleAll($_POST)。问题是$vars数组中存储的变量必须命名为"var1"&"var2"等。这意味着处理代码与html表单元素的名称或url中的get变量(或者传入的任何数组的键)相耦合。

允许注入任何变量的数组使该方法变得灵活,这是必要的,因为它也是多态的。类继承这个方法并使用它来调用它自己的操作。这样做的结果是,从外部看,处理方法需要什么才能发挥作用并不明显。这意味着必须对实现进行检查,以了解它的作用(除非我将代码复制到phpdoc中,否则这将是愚蠢的)。

我不知道该怎么避开这个。在索引页上公开大量的if/case语句(来自像这样的多个类)会导致代码极其混乱,因此最好将所有这些封装在一个方法中。此外,将其作为类的一个方法来负责调用操作其自身状态的操作也是有意义的(责任驱动的设计)。我曾考虑将每个变量作为方法的参数,但对于某些类,参数列表会非常大。此外,这意味着不同类的许多handleAll()方法无法自动调用,因为每次调用都需要显式注入所有参数,从而删除多态方面。

总之,我需要保持该方法的多态性,但我需要某种方式将处理代码与html表单或url中的用户输入解耦。在这样做的过程中,也许还有一种将接口与实现分离的方法。我很惊讶我已经找不到任何解决方案了,这似乎是一个常见的问题。

我不确定你所描述的是否可以避免。

如果您的代码需要特定的参数,无论是以包含特定值的数组形式还是其他形式,该函数都将始终取决于正确填充的参数。

如果我有function foo($a, $b, $c),我将始终需要填充参数。如果它们来自POST,那么我需要从POST中获取它们。即使函数使用array('a' => ..., 'b' => ..., 'c' => ...),情况也是如此。

但是,如果您想将表单与参数列表解耦,可以使用一个简单的函数将POST数组转换为某个处理程序函数所期望的格式。不过,我真的看不出有什么原因,因为如果不必的话,为什么要增加额外的复杂性呢?

如果您希望更好地定义处理程序需要什么样的数组,可以考虑让它需要一个对象。这种方法有时被称为参数对象。

使用参数对象的好处是,您可以轻松地在构造函数中设置所需的参数,并对可选参数使用setter。任何使用代码的人都可以查看对象的接口,看看需要什么值。

如果处理程序使用的值实际上是相互关联的,我会考虑创建一个实际的业务逻辑类型对象。使用POST中的数据创建它,并将处理值的代码移动到对象中的方法中。

解耦和自动化处理方法也可能是缩小范围的痛苦方法。但除了为每件事创建处理程序之外,没有太多的选择。不过,我想你补充一下。允许默认值并支持变体

function handlePOST() {    }
function handleGET()  {    }
function handleArr()  {    }

现在,这些函数可以代表它们保存函数的变体。

然而,在内部,除了对所有处理程序进行编码之外,它们并不是更好的方法。但交换机缩短了它们,并使用单独的功能进行处理。

switch($_POST['var1']) {
    case "value1": callPostValue1(); break;
    default: callPostDefaultHandler(); break;
}