如何在编程中进行良好的验证?

时间:2011-06-25 05:12:58

标签: php validation error-handling

这是一个问题,我想开发自己的一套API,它会与其他人分享,当我开发这个API时,我无法确保其他人正在做正确的事情......我想提供一个简单说你好程序... 在任何错误检查和验证中将有这样的事情:

function sayHello($yourName){
echo($yourName);
}

然后,有些人可能不知道应该传递$ yourName params的内容,并包含类型检查,所以我会增强这样的东西......

/**
 * Say hello to someone.
 *
 * @param string $aName
 **/

function sayHello($yourName){

    if (!is_string($aName)) {
        throw new ArgumentException("Type not correct.");
    }

    echo($yourName);
}

好的,我可能会进一步检查,例如,用户可能会向我传递一个空字符串或非常长的字符串,所以我也需要避免这样做,所以我的代码将变成这样:

/**
 * Say hello to someone.
 *
 * @param string $aName
 **/

function sayHello($yourName){

    if (!is_string($yourName)) {
        throw new ArgumentException("Type not correct.");
    }
    if(strlen($yourName)) == 0 || strlen($yourName)) > 100){
        throw new ArgumentException("argument length is invalid.");
    }

    echo($yourName);
}
好吧,即使是最坏的情况,我的函数中也有一些业务逻辑,例如,我的函数只允许英文名称,所以,我会有更复杂的东西:

/**
 * Say hello to someone.
 *
 * @param string $aName
 **/

function sayHello($yourName){

    if (!is_string($yourName)) {
        throw new ArgumentException("Type not correct.");
    }
    if(strlen($yourName)) == 0 || strlen($yourName)) > 100){
        throw new ArgumentException("argument length is invalid.");
    }
    if(!isEnglishName($yourName)){
        throw new ArgumentException("argument business logic is wrong.");
    }

    echo($yourName);
}

正如你所看到的,只有这个简单的sayHello程序才能从3行代码变得更多,它只是一个简单的函数,考虑我更复杂的逻辑,我该如何简化那个过程?我可以采取什么样的战略?谢谢。

3 个答案:

答案 0 :(得分:2)

精彩的例子!

简而言之 - 不要验证任何东西,这不值得所有进一步的痛苦。

  • 你必须写出来 - 这很难(3条规则,甚至可能更糟)
  • 它们通常在不同的地方重复(比如你好,setDefaultHello等) - 因为你没有合适的类型(名字),你仍然只是“限制”字符串。
  • 你必须抛出异常 - 但是哪一个?

我知道这听起来有多糟糕(我完全无视接触式设计,我有多糟糕!),但是:

  • 无论如何限制输入参数是什么意思?
  • 你真的想禁止传递物品吗?
  • 是关于“做”还是“限制”的代码?专注于你的目标 - 必须做什么,而不是何时何地。
  • 哪个版本更具可读性?是否有验证?

特别是最后一个应该令人信服。

<强>要点:

  • 您可以介绍Name类(以及所有类型的许多其他类)
  • 或者您可以进入duck-typing

我建议后者。如果你还没有意见,试试吧,你可以随时回到合同设计。永远不要把它们混合在一起。

答案 1 :(得分:1)

至于处理用户输入,现代Web框架允许验证所有Web表单。这是一个例子(不是从任何特定框架中获取):

$validation()->item('name')->add_rule(array('required', 'min_length[2]','max_length[20]' 'is_english', 'is_string'));

你知道,验证仍然存在,但代码已被抽象出来并集中在其他类中,您可以在其中重用该功能。

然后,不是在整个地方复制代码,而只是配置表单。

答案 2 :(得分:0)

逻辑上,您可能无法简化流程。

您可以在函数中放置名称验证,以便使顶级代码更容易理解,但您必须在某处进行这些验证。特别是在用户键入$yourName的情况下,在您的示例中可能如此。

考虑这个要求的类比:你必须检查你调用的每个函数的错误返回。这里没有什么不同。

你真的别无选择:如果你没有检查任何功能的错误,你就在你的程序中放了一颗定时炸弹。这里也是如此:您必须验证函数输入。

令人沮丧的是,发现参数验证所需的代码与函数的核心操作一样多。但就是这样。没有办法解决它。